Quick answer: A SCORM course that runs correctly but records as incomplete almost always has one of seven causes: the content never called Terminate or LMSFinish before the window closed, the content set an exit value of suspend so the LMS is deliberately holding the attempt open, the LMS is checking success status while the content only reported completion status, suspend data exceeded the size limit for the SCORM version in use, the content could not reach the LMS API object because of a cross-domain iframe or blocked cookies, a mastery score threshold was not met, or the platform's attempt handling overwrote an earlier completion. Diagnose by checking what the LMS actually recorded for lesson status, completion status, success status, score, and exit before changing anything.
The report says incomplete. The learner insists they finished. The course displayed a completion screen. Everyone is right, and the problem sits between the content and the platform rather than with either party.
SCORM defines how packaged content communicates with a learning platform at runtime. Completion is not something the LMS observes; it is something the content reports through specific data model elements. If the content never reports it, reports the wrong element, or cannot reach the communication interface at all, the LMS has no way to know the course was finished.
This guide is a diagnostic sequence for administrators. It covers what to check first, the common causes in the order they occur, and how to test each one. It assumes familiarity with the basic differences between the standards; if that is not settled yet, our guide to SCORM, AICC, and xAPI covers the ground first.
Before You Change Anything, Read the Record
The most common mistake is reassigning the course before looking at what the LMS actually stored. The stored values usually identify the cause within a minute.
Pull the raw tracking data for that learner and that attempt, not the summary status shown in a report. Depending on your platform this may be under a debug view, a detailed attempt report, or an administrator-only tracking panel. What you want is the data model values the content sent.
| Value to Check | SCORM 1.2 Element | SCORM 2004 Element | What It Tells You |
|---|---|---|---|
| Lesson or completion status | cmi.core.lesson_status | cmi.completion_status | Whether the content reported finishing at all |
| Pass or fail outcome | Combined into lesson_status | cmi.success_status | Whether an assessment threshold was met |
| Score | cmi.core.score.raw | cmi.score.raw and cmi.score.scaled | Whether a mastery threshold applies and was met |
| Exit behavior | cmi.core.exit | cmi.exit | Whether the attempt was suspended on purpose |
| Session time | cmi.core.session_time | cmi.session_time | Whether a session was recorded at all |
| Bookmark state | cmi.core.lesson_location | cmi.location | Whether resume data was stored |
| Suspend data | cmi.suspend_data | cmi.suspend_data | Whether state data may have hit a size limit |
If every value is empty, the content never successfully communicated with the LMS and the problem is connection, not completion. If the values are populated but the status is incomplete, the content communicated fine and something about the completion logic is the issue. That single distinction splits the diagnosis in two.
Cause One: The Session Never Closed Properly
SCORM content is expected to call a termination method, LMSFinish in SCORM 1.2 or Terminate in SCORM 2004, to commit the session and hand control back to the platform.
If a learner closes the browser tab, the laptop sleeps, the connection drops, or the device is locked mid-session, that call may never happen. Depending on how the content handles committing data, some or all of the session may be lost, including the completion the learner just earned.
How to spot it. Session time is missing or unrealistically short while other values look partially populated. The learner reports finishing and closing the window rather than using an exit button.
What to do. Check whether the content commits data progressively or only at the end. Well-built content commits at intervals; older content sometimes commits only on exit. Instruct learners to use the course exit or close button rather than the browser tab close, and confirm the course actually has one. Where a population is frequently interrupted, this problem compounds badly, which is one of the practical issues covered in our guide to training deskless and shift-based employees.
Cause Two: The Attempt Was Suspended Deliberately
This one looks like a bug and is usually correct behavior.
When content sets the exit value to suspend, it is telling the platform that the learner intends to return and that the attempt should remain open with its state preserved. A suspended attempt is legitimately incomplete, because from the platform's perspective it is still in progress.
Some content sets suspend on every exit as a default, including the final one. The learner finishes, closes the course, the exit value says suspend, and the attempt stays open forever.
How to spot it. Exit is set to suspend, bookmark and suspend data are populated, and the learner reports reaching the end.
What to do. Confirm with the content provider how exit is handled on final completion. Some platforms offer an administrative option to close suspended attempts or to treat a completion status as authoritative regardless of exit. This is a content behavior rather than a platform fault, so the fix generally sits with the publisher.
Cause Three: Completion and Success Are Being Confused
This is the single most common cause in mixed-version environments, and it comes from a real structural difference between the SCORM versions.
SCORM 1.2 uses one field, cmi.core.lesson_status, for both ideas. Its permitted values include passed, failed, completed, incomplete, browsed, and not attempted. Content that reports completed has said nothing about whether an assessment was passed, and content that reports passed has said nothing explicit about completion.
SCORM 2004 separates them into cmi.completion_status, which holds completed, incomplete, or unknown, and cmi.success_status, which holds passed, failed, or unknown. Content can legitimately be completed and failed at the same time.
The mismatch appears when the LMS completion rule looks for one thing and the content reports the other. A course that sets completion_status to completed will show as incomplete on a platform configured to require success_status of passed.
How to spot it. One status field is populated correctly and the other is unknown or empty, while the platform's completion rule points at the empty one.
What to do. Check the course-level completion setting in your LMS. Most platforms allow you to define whether completion requires completion status, success status, a score threshold, or a combination. Align that setting with what the content actually reports rather than with what seems logical. Ask the provider which elements the course sets and under what conditions.
Cause Four: Suspend Data Exceeded the Limit
Content stores its internal state, such as which pages were visited and which questions were answered, in cmi.suspend_data. Both SCORM versions define a size limit for that field, and the difference between them is substantial.
SCORM 1.2 specifies a maximum of 4,096 characters. SCORM 2004 raised that to 64,000 characters. Content built against the larger allowance but published as a SCORM 1.2 package, or a long course with extensive branching and question tracking, can exceed what the platform will store. When that happens the data is typically truncated or rejected, and the content's ability to reconstruct its own state on resume breaks. Symptoms include a course that restarts from the beginning, loses answered questions, or never reaches a completion condition because it cannot tell that earlier sections were finished.
How to spot it. Long or heavily branched courses. Failures concentrated among learners who took several sessions rather than one. Stored suspend data sitting at or just under 4,096 characters, which strongly suggests truncation rather than coincidence.
What to do. Confirm which SCORM version the package uses and what limit your platform enforces, since some platforms are more permissive than the specification requires and others are not. Ask the provider whether a SCORM 2004 package is available, or whether the course can be split into smaller units. Test by completing the course in one sitting; if that works while multi-session attempts fail, state persistence is the likely cause.
Cause Five: The Content Cannot Reach the LMS API
SCORM content finds the platform's communication interface by searching the parent and opener window chain for a specific JavaScript object, named API for SCORM 1.2 and API_1484_11 for SCORM 2004. If it cannot find that object, it cannot report anything at all.
Several conditions break that search. Content hosted on a different domain and loaded in an iframe is blocked by browser same-origin policy from reaching the parent window. A popup blocker preventing the content window from opening severs the opener relationship. Browser settings blocking third-party cookies or storage can break session handling in cross-domain setups. Mixed content, meaning insecure content loaded inside a secure page, is blocked outright by modern browsers.
How to spot it. All tracking values are empty. The course itself displays and runs normally. The learner may have seen an error mentioning that the API could not be found, or nothing at all. The problem is frequently browser-specific or affects one site or network.
What to do. Reproduce it in the affected browser with the developer console open and look for API or security errors. Test in a different browser and with strict privacy settings disabled to confirm the pattern. Check whether the content is served over HTTPS from the same origin as the platform, and confirm popup permissions. Where content is hosted by the provider rather than imported, this becomes an integration question rather than a package question, and the trade-offs are covered in our guide to SCORM Dispatch versus native content.
Confirm Delivery Formats Before You Deploy
Browse the live catalog and check the delivery formats, standards, and versions available for each title so compatibility is confirmed at the course level rather than discovered after rollout.
Cause Six: A Score Threshold Was Not Met
Where a course carries a mastery score, the platform may withhold completion until the reported score meets it, even when the content reported completion.
This becomes confusing when the threshold is defined in two places. A value may be set in the package manifest and another in the platform's course settings, and they may disagree. Score scaling adds a further wrinkle, since SCORM 2004 supports a scaled score between zero and one alongside a raw score, and a platform comparing the wrong one against a percentage threshold will produce results that look arbitrary.
How to spot it. Completion status is set correctly, a score is recorded, and the score sits below the configured threshold. Learners with high scores complete normally while others do not.
What to do. Compare the mastery score in the manifest with the setting in the LMS and remove the conflict. Confirm which score field the platform evaluates. Decide deliberately whether completion should require passing at all, since for awareness-level content it often should not.
Cause Seven: The Attempt Structure Is Not What You Think
Retakes and multiple attempts introduce behavior that varies by platform.
Some platforms create a new attempt and treat it as authoritative, meaning a second incomplete attempt overwrites a first completed one in the reported status. Some retain the highest or first completion. Some allow a learner to reset progress, discarding earlier data. Where a course was updated and republished, learners may be looking at a different package version than the one their record relates to.
How to spot it. The learner completed the course, opened it again out of curiosity, and the status reverted. Or the course was updated recently and completions before the update behave differently from those after.
What to do. Review the platform's attempt handling and version-change behavior before republishing content. Establish whether an updated package resets learner progress, because for recurring compliance content that decision has real consequences, particularly where records must be defensible. Retention and record content requirements are covered in our guide to how long to keep employee training records.
A Diagnostic Order That Saves Time
Work through these in sequence rather than testing at random.
First, pull the raw tracking values for the affected attempt. If everything is empty, go straight to the API connection check. If values are present, continue.
Second, check exit. If it says suspend, the attempt is being held open deliberately and the question is content behavior.
Third, compare what the content reported against what your completion rule requires. Completion status against success status is the most frequent mismatch.
Fourth, check the score against any mastery threshold, in both the manifest and the platform setting.
Fifth, if failures concentrate among multi-session learners, investigate suspend data limits and the SCORM version.
Sixth, if failures concentrate by browser, network, or site, investigate the API connection, cookies, popups, and mixed content.
Seventh, if the pattern involves retakes or a recent content update, examine attempt handling and versioning.
Record what you find for each course rather than solving it individually each time. Most organizations discover that two or three courses account for nearly all their completion tickets, and those courses usually share a root cause.
Preventing the Problem at Procurement
Most SCORM completion issues are decided before deployment, when a package is selected and imported without being tested against realistic conditions.
Test the actual package rather than a demonstration. Complete it, fail it, retake it, abandon it mid-way and resume, and close the browser without exiting properly. Do this on the browsers, devices, and network conditions your workforce actually uses, including mobile and any site with restricted connectivity.
Ask the provider directly which SCORM version and edition the package targets, which data model elements it sets and when, how it handles exit on final completion, whether it commits progressively, and what its suspend data footprint looks like. Those questions are answerable and rarely asked. They belong alongside the wider evaluation criteria in the training content marketplace buyer checklist and the vetting considerations in training marketplace quality assurance.
Where completion records support a regulatory obligation, this testing is not optional. A course that intermittently fails to record completion produces an evidence gap that only becomes visible during an audit, and the obligations that depend on it are set out in mandatory compliance training requirements and what makes a compliance course legally defensible.
When the Answer Is a Different Delivery Method
Some completion problems are structural rather than fixable, and continuing to troubleshoot a package is the wrong response.
Where content is hosted by the provider and launched rather than imported, LTI addresses several of the failure modes above by design, since identity, launch, and service exchange are handled through a defined security model instead of a JavaScript object in a window chain. The trade-offs are covered in our native LMS versus LTI integration guide and on the Marketplace and LTI integration page, with a comparison of the two paths on our native versus LTI page.
LTI is not automatically simpler, and its own failure modes are real. Our guide to the signs an LTI integration is more trouble than a native platform covers when to stop persisting with an integration entirely.
Where the underlying platform is the constraint rather than the content, the options include delivering into a different system, using a native environment such as the one described on our LMS overview, or reviewing platforms that ship with content already integrated, covered in learning management systems with built-in content. Reducing the number of systems a completion record has to cross also reduces the number of places it can be lost, which is part of the case made in LMS and HRIS integration.
What to Do With This Next
A SCORM course showing incomplete is reporting something specific, and reading the stored data model values identifies which of a small number of causes is operating. Empty values mean the content never reached the platform. Populated values with an incomplete status mean the completion rule and the content disagree.
Check the record before reassigning anything. Look at exit, completion status, success status, score, and suspend data in that order. Test the failure and resume paths rather than only the clean completion, because those are the paths learners actually take. And ask content providers the version and behavior questions before deployment, since almost every recurring completion problem was decided at import.
Teams reviewing delivery formats before rollout can check available options in the corporate content marketplace, and the reporting side of completion evidence is covered in reporting that matters, course performance metrics, and measuring learning effectiveness. For content being added to an existing platform, the integration route is set out in adding third-party training content to your LMS.
Review Compatibility for Your Environment
Discuss standards support, delivery options, and completion reporting for your specific LMS configuration, and run a compatibility test on representative courses before committing to a rollout.
Technical References
On the SCORM data model elements and version differences described above: Advanced Distributed Learning, SCORM
On testing a package against the specification before deployment: Advanced Distributed Learning, SCORM 2004 Fourth Edition Test Suite
On the LTI launch and service model referenced in the final section: 1EdTech, Learning Tools Interoperability




