Why SCORM Completion and Course Completion Disagree in Moodle
A SCORM module reports completed, but the activity never ticks complete and the course never finishes. The status the package sends and the status Moodle's completion rule requires are two different things that have to be told to match.
A learner finishes a SCORM module and the player shows it as completed, yet Moodle leaves the activity (and therefore the course) incomplete, blocking certificates and compliance reporting. The cause is almost always a mismatch between the runtime status the SCORM package reports and the status the activity’s completion condition requires, compounded by the fact that course completion is recalculated on a schedule, not instantly. This guide explains the three layers of “complete” in Moodle, how to see what your package actually reported, and how to fix the mismatch. Paths and SQL are for Moodle 4.5.
The three layers of “complete”
The word “complete” means three different things at three different layers, and a learner is only finished when all three agree:
- The SCORM runtime status – what the package itself reports back to Moodle (for example
cmi.core.lesson_status = completed). - Activity completion – Moodle’s own decision about whether the SCORM activity is complete, based on the conditions you configured on that activity.
- Course completion – whether the course is complete, based on the activities and criteria you nominated, recalculated by a scheduled task.
A breakdown at any layer stops the chain. The most common failure is between layers 1 and 2.
Layer 1: what the SCORM package reports
SCORM 1.2 and AICC report a single field, cmi.core.lesson_status, which can be passed, completed, failed, incomplete, browsed, or not attempted.
SCORM 2004 splits this into two separate fields: cmi.completion_status (completed / incomplete) and cmi.success_status (passed / failed). This split matters: in Moodle, for a SCORM 2004 package the only status treated as complete is cmi.completion_status = completed. A package that reports success_status = passed but leaves completion_status at incomplete will never satisfy a completion-status condition.
The quickest way to see exactly what your package reported is in the interface: open the SCORM activity, go to Reports, click the learner’s attempt, and open Track details. The reported status is shown there. If you would rather query it directly, the tracking tables in Moodle 4.5 are:
SELECT a.userid, e.element, v.value
FROM mdl_scorm_scoes_value v
JOIN mdl_scorm_attempt a ON a.id = v.attemptid
JOIN mdl_scorm_element e ON e.id = v.elementid
WHERE a.scormid = ?
AND e.element IN ('cmi.core.lesson_status', 'cmi.completion_status', 'cmi.success_status')
ORDER BY a.userid;
(These tables were restructured in Moodle 4.x; on 4.0 and earlier the equivalent data lived in a single mdl_scorm_scoes_track table.)
Layer 2: the SCORM activity’s completion conditions
A SCORM activity offers three completion conditions in the Activity completion section of its settings:
- Require status – a set of checkboxes (Passed, Completed, Failed, Incomplete, Browsed, Not attempted). The activity is marked complete when the reported status matches at least one of the ticked statuses.
- Require minimum score – the activity is complete only when the SCORM score reaches the value you set.
- All SCOs must return completion status – every SCO in a multi-SCO package must report a status, not just the launch SCO.
This is where the mismatch lives. If your package reports completed but Require status has only Passed ticked, the condition is never met and the activity never completes, even though the player clearly showed “completed”. The reverse is equally common: a package reports passed, but only Completed is ticked.
You can confirm the resulting activity-completion state per learner:
SELECT cmc.userid, cmc.completionstate
FROM mdl_course_modules_completion cmc
JOIN mdl_course_modules cm ON cm.id = cmc.coursemoduleid
WHERE cm.instance = ? -- the SCORM instance id
AND cm.module = (SELECT id FROM mdl_modules WHERE name = 'scorm');
completionstate is 0 (incomplete), 1 (complete), 2 (complete with pass), or 3 (complete with fail).
Layer 3: course completion and the recalculation lag
Course completion is configured under Course > More > Course completion. To make the SCORM activity count, add it under Condition: Activity completion and check whether the overall condition requires all selected activities or any of them.
Two things commonly trip people here:
- The SCORM activity is complete, but it was never added as a course-completion criterion, so the course can never complete on the back of it.
- The activity is complete, but the course still shows incomplete for a while. Course completion is not recalculated the instant an activity completes; it is processed by the scheduled task
coretaskcompletion_regular_task. Until the next run (or the learner reloads the course), the course status lags behind the activity status.
You can see which activities the course depends on:
SELECT course, criteriatype, moduleinstance
FROM mdl_course_completion_criteria
WHERE course = ?;
A criteriatype of 4 is an activity-completion criterion; moduleinstance is the course-module id of the activity.
Fixing it
- Match the required status to what the package reports. Open the SCORM activity, go to Activity completion, and under Require status tick the status your package actually sends (confirmed in Track details or the query above). If you are unsure what it sends, tick both Passed and Completed; the learner only needs to satisfy one of them.
- For SCORM 2004 packages, ensure the package sets
cmi.completion_status = completed. If it only setssuccess_status, the completion-status condition will not be met; either fix the package or base completion on the minimum score instead. - Check the “All SCOs” condition. If the package has multiple SCOs (for example a menu plus content SCOs) and one never reports a status, untick All SCOs must return completion status or fix the package so every SCO reports one.
- Add the activity to course completion and confirm the any/all aggregation matches your intent.
- Allow for the recalculation lag, or trigger it. After fixing the conditions, course completion updates on the next cron run. To verify immediately, run cron (
php admin/cli/cron.php) or have the learner reload the course.
Re-checking existing learners
Changing a completion condition does not always retro-apply cleanly to learners who already attempted the activity. After adjusting the condition, use Reports > Activity completion and Course completion to confirm the affected learners now show complete, and run cron so course completion catches up. For a learner whose attempt predates the fix, a fresh review of completion (or, in stubborn cases, re-marking the attempt) may be needed.
Related
If your problem is a numeric pass/fail rather than a status mismatch (a learner sees a passing score on screen but Moodle records a fail), that is a different failure mode caused by grade rounding. See our guide on SCORM and quiz grade rounding for that case.
Solin specializes in Moodle and Totara completion, SCORM, and certification workflows. Contact us if a completion problem is blocking your reporting.
Need help with a Moodle or Totara project?
Contact us