When your organization switches LMS vendors, the SCORM content library is the first thing that breaks. Completion records disappear. Courses launch blank screens. Tracking silently fails while passing no errors. This guide walks through the full technical process of migrating SCORM 1.2 and SCORM 2004 4th Edition packages between platforms – covering package validation, manifest compatibility, data model field mapping, historical record preservation, and the six error patterns that account for over 80% of post-migration failures. All API specifications referenced here align with the ADL SCORM Run-Time Reference (scorm.com) and the xAPI 1.0.3 specification published by ADL in April 2013.
The SCORM Package Architecture You’re Actually Moving
Before touching any migration tooling, you need to understand what a SCORM package is at the file level – not the marketing definition.
A SCORM package (Package Interchange Format, or PIF) is a .zip archive. Its structure is non-negotiable:
course_package.zip
├── imsmanifest.xml ← REQUIRED: must be at root, not in subfolder
├── adlcp_rootv1p2.xsd ← SCORM 1.2 schema reference
├── index.html ← Launch file (href in manifest)
├── scormdriver/
│ └── APIWrapper.js ← JavaScript runtime bridge
├── content/
│ ├── module1.html
│ └── assets/
└── res/
└── quiz_data.js
The imsmanifest.xml defines everything the LMS needs: course structure, SCO identifiers, launch parameters, mastery score, sequencing rules (2004 only), and resource references. If the manifest is not at the ZIP root, the LMS cannot import the package – this is the single most common upload failure across Moodle, Canvas, TalentLMS, and Docebo.
SCORM 1.2 vs. SCORM 2004 4th Edition: The Data Model Differences That Cause Migration Failures
These two versions are not interchangeable. When migrating to a new LMS, misidentifying which version your packages use will silently corrupt tracking data.
| Property | SCORM 1.2 | SCORM 2004 4th Edition |
|---|---|---|
| API Initialization | LMSInitialize(“”) | Initialize(“”) |
| API Termination | LMSFinish(“”) | Terminate(“”) |
| Set Value | LMSSetValue(element, value) | SetValue(element, value) |
| Get Value | LMSGetValue(element) | GetValue(element) |
| Completion field | cmi.core.lesson_status (single field) | cmi.completion_status + cmi.success_status (split) |
| Suspend data limit | 4,096 characters | 64,000 characters |
| Score field | cmi.core.score.raw | cmi.score.raw |
| Session time | cmi.core.session_time (HHHH:MM:SS.SS) | cmi.session_time (ISO 8601 duration: PT1H30M) |
| Sequencing | Not supported | Full IMS SS&N (4th Ed.) |
| Jump navigation | Not supported | adl.nav.request = jump |
| Mastery override | adlcp:masteryscore in manifest | imsss:minNormalizedMeasure in sequencing rules |
The session time format difference alone causes silent failures when the target LMS strictly validates ISO 8601 on SCORM 2004 packages but receives HHHH:MM:SS format from a content package published against the wrong specification.
SCORM 1.2 lesson_status values
incomplete | completed | passed | failed | browsed | not attempted
SCORM 2004 split-status values
cmi.completion_status: completed | incomplete | not attempted | unknown
cmi.success_status: passed | failed | unknown
The split is not cosmetic. A learner can complete a module (viewed all slides) but fail the assessment – SCORM 1.2 cannot express this without ambiguity. When migrating 1.2 packages to a 2004-native LMS, the completion logic must be remapped or the new LMS will report statuses incorrectly.
LMS × SCORM Standards Compatibility Matrix (Verified March 2026)
This table reflects vendor documentation and ADL Conformance Test Suite (STS) results. “Full” = passes ADL STS for that edition. “Partial” = known gaps in sequencing, interaction tracking, or objective handling.
| LMS Platform | SCORM 1.2 | SCORM 2004 3rd Ed. | SCORM 2004 4th Ed. | xAPI 1.0.3 | cmi5 | Notes |
|---|---|---|---|---|---|---|
| Moodle 4.x | Full | Full | Full | Full | Partial | iFrame delivery; enforce popup for 2004 sequencing |
| Canvas (Instructure) | Full | Full | Partial | Via LTI | No | Use New Quizzes for 2004; known S&N gaps |
| Cornerstone OnDemand | Full | Full | Full | Full | Yes | Requires content upload via Admin > Content > SCORM |
| Docebo | Full | Partial | Full | Full | Yes | 3rd Ed. sequencing has known defects per vendor docs |
| TalentLMS | Full | Full | Full | Full | No | Max package size 1GB; popup window recommended |
| Absorb LMS | Full | Full | Full | Full | Yes | – |
| SAP SuccessFactors | Full | Full | Partial | Full | No | 4th Ed. weighted rollup not fully supported |
| HealthStream | Full | No | No | Limited | No | Healthcare-specific; stay on SCORM 1.2 |
| Relias | Full | Partial | No | Partial | No | Healthcare-specific; 1.2 only for compliance courses |
| Blackboard Ultra | Full | Full | Full | Full | Partial | Legacy Bb Learn has SCORM 2004 edge-case failures |
| D2L Brightspace | Full | Full | Full | Full | Yes | Best-in-class SCORM 2004 4th Ed. conformance |
| Totara Learn | Full | Full | Full | Full | Yes | External package mode loses grade passback |
Authoring tool defaults (March 2026):
- Articulate Storyline 360: defaults to SCORM 1.2; 2004 4th Ed. available in Publish settings
- Adobe Captivate: defaults to SCORM 1.2; all editions selectable
- Lectora Publisher: supports all editions
- iSpring Suite: defaults to SCORM 1.2; 3rd/4th Ed. available
- Dominknow Claro: publishes to all editions and xAPI natively
Healthcare LMS note:
If your organization uses HealthStream, Relias, or similar compliance-first platforms, maintain SCORM 1.2 as your default output and publish 2004 packages separately for non-clinical LMS targets. SCORM 2004 3rd Edition (released 2006) has known interoperability defects and should not be targeted for new content.
Implementation: Pre-Migration Checklist and Platform-Specific Steps
Phase 1: Content Audit and Package Validation
Before any migration work starts, audit every SCORM package in your library.
Step 1 – Identify SCORM version per package
Open each .zip and inspect the imsmanifest.xml declaration:
<!– SCORM 1.2 identifier –>
<metadata>
<schema>ADL SCORM</schema>
<schemaversion>1.2</schemaversion>
</metadata>
<!– SCORM 2004 4th Edition identifier –>
<metadata>
<schema>ADL SCORM</schema>
<schemaversion>2004 4th Edition</schemaversion>
</metadata>
If schemaversion is missing or malformed, the LMS will attempt auto-detection, which produces inconsistent results across platforms.
Step 2 – Validate against SCORM Cloud before uploading to target LMS
SCORM Cloud (by Rustici Software) is the reference implementation of the SCORM runtime. Run every package through it before attempting LMS import. A package that fails in SCORM Cloud will fail everywhere. A package that passes SCORM Cloud but fails in your target LMS isolates the problem to the LMS implementation – a useful distinction when engaging vendor support.
Test URL: https://cloud.scorm.com
Upload package → Launch as learner → Complete course → Inspect tracking report
Check specifically: lesson_status / completion_status, score.raw, suspend_data (approach the 4,096-char limit on 1.2 packages), and session_time format.
Step 3 – Export completion records from the source LMS before cutover
Most LMS platforms export user completion data as CSV. Capture at minimum:
- User ID (map to target system’s user ID field)
- Course/SCO identifier
- Completion status (as raw string, not normalized)
- Score
- Date of completion
- Number of attempts
- Certificate expiry (if applicable)
Critical:
Many LMS platforms store only the most recent attempt, discarding earlier records. Audit this before migration – regulated industries (healthcare, finance, manufacturing) may have retention obligations. Confirm your data retention policy with compliance before purging anything from the source system.
Phase 2: Platform-Specific Upload Configuration
- Navigate to Course → Add Activity → SCORM Package
- Set “Display package” to “New window” for SCORM 2004 with sequencing – iFrame mode breaks S&N in some browsers
- Under “Compatibility settings,” set “Force completed” to OFF unless explicitly overriding tracking
- Set “Mastery score overrides status” per your course logic (enabling this changes the lesson_status behavior when a mastery score exists in the manifest)
- Do not overwrite an existing SCORM activity by re-uploading a package with a different <item identifier> in the manifest. Moodle deletes all tracking data for SCO identifiers that no longer exist in the manifest.
- Course Manager → Add Content → SCORM/AICC
- Select version manually (do not rely on auto-detect for SCORM 2004)
- Under Tracking tab, map completion trigger to the correct cmi field for your content type
- Enable “Force completion” only if the content does not fire Terminate() reliably on exit
- Courses → Add Content → SCORM/xAPI
- Maximum package size is 1 GB; pre-compress video assets if migrating large media-heavy packages
- Launch in popup window for SCORM 2004 – TalentLMS iframe mode has known issues with sequencing and JavaScript window.parent API calls
- Set Completion rule to “Passed/Failed” if the course uses lesson_status: passed rather than completed
- Admin → Content → Add Content → SCORM
- Version selection must match the manifest declaration exactly
- Enable “Track using” → select the appropriate CMI field; default is lesson_status which is correct for SCORM 1.2 but incorrect for 2004 courses that only set completion_status
Phase 3: Historical Record Import
Most LMS platforms do not have a native API for importing historical completions. Options:
- CSV batch import (available in Docebo, Cornerstone, TalentLMS, Absorb): Import completion records as pre-completed registrations. Verify that imported records respect the original completion date – some platforms default to import date.
- LMS vendor migration service: For enterprise migrations with compliance requirements, engage the vendor’s professional services team to import records at the database level.
- Read-only legacy access: Retain read-only access to the source LMS for a minimum of 60 days post-cutover for audit trail purposes.
Common Issues and Fixes
Error 1: “Missing imsmanifest.xml” on upload
Cause: The file is in a subfolder inside the ZIP, not at the root. This happens when you right-click a folder and “Compress” – the resulting ZIP wraps the folder.
Fix: Navigate inside the exported SCORM folder, select all files, then compress. The imsmanifest.xml must appear immediately when the ZIP is opened, not inside a directory. Validate with: unzip -l package.zip | grep imsmanifest.
Error 2: Completion status never updates / stays “incomplete”
Cause (SCORM 1.2): The course calls LMSFinish(“”) but never sets cmi.core.lesson_status before terminating. The LMS receives a termination signal with no status.
Cause (SCORM 2004): The course sets cmi.completion_status correctly but the LMS is configured to look at cmi.success_status only.
Fix: In your LMS admin settings, verify which CMI field drives the completion trigger. In SCORM Cloud debug mode, confirm the sequence: SetValue(“cmi.completion_status”, “completed”) → Terminate(“”). If the course doesn’t fire Terminate() on tab close (a common authoring tool bug), enable the “Auto-save on exit” or equivalent setting in your LMS.
Error 3: Learner progress lost on resume (suspend_data truncation)
Cause: Package published as SCORM 1.2 with suspend_data exceeding 4,096 characters. Data is silently truncated; the course cannot reconstruct learner state on re-entry.
Fix: Republish as SCORM 2004 3rd or 4th Edition (64,000-character limit). If you must stay on 1.2, reduce course complexity or split into multiple shorter SCOs. Check your authoring tool’s suspend_data usage under debug mode – Articulate Storyline shows this in the SCORM output log.
Error 4: CORS errors / blank screen on launch
Cause: SCORM content hosted on a CDN or external server makes API calls to a domain different from the LMS origin. Modern browsers block cross-origin JavaScript calls unless the server explicitly allows them.
Fix: Configure Access-Control-Allow-Origin headers on the content server. Alternatively, host SCORM content on the same domain as the LMS. For older content referencing absolute HTTP URLs in the manifest, update all resource href values to relative paths or HTTPS.
Error 5: “Found more than one record” in Moodle SCORM 1.2
Cause: The imsmanifest.xml has duplicate <organization identifier> or <item identifier> values. This violates the SCORM 1.2 spec and causes Moodle to reject or mistrack the package.
Fix: Open imsmanifest.xml and ensure all identifier attributes within <organizations> and <item> elements are globally unique within the manifest. Many older authoring tools generate identical identifiers when courses are duplicated from templates.
Error 6: Mastery score overriding intended completion logic
Cause: Many authoring suites write a <adlcp:masteryscore> node to the manifest by default – even for courses that don’t use score-based completion. When the LMS evaluates this value, it overrides lesson_status based on the learner’s raw score, producing unexpected failed statuses for content-completion courses.
Fix: Remove the <adlcp:masteryscore> node from the manifest, or explicitly set it to 0 if the course uses score-based passing. In Moodle, the “Mastery score overrides status” setting controls this behavior at the activity level.
Tip from the field:
When migrating a large library, create a staging LMS environment that mirrors your production configuration exactly – same version, same SCORM player settings, same popup/iframe mode. Run the 10 most complex courses (branching scenarios, large suspend_data payloads, multiple SCOs) through the staging environment before any live migration. LMS vendors will tell you their platform is SCORM-compliant; what they won’t tell you is which specific CMI elements they handle non-standardly. The only way to find the edge cases is to run your actual content, not sample packages. SCORM Cloud will also tell you whether a failure is in your content or in the LMS – this distinction is worth hours of vendor support calls.
Frequently Asked Questions
Q1. Can I migrate SCORM 1.2 packages to an LMS that only supports SCORM 2004, without republishing from source?
Only partially. The package structure and manifest schema differ between versions – a SCORM 1.2 manifest uses ADL SCORM 1.2 schema declarations, and the runtime API calls (LMSInitialize, LMSFinish, LMSSetValue) are different from SCORM 2004 equivalents (Initialize, Terminate, SetValue). Most modern LMSs maintain a backward-compatible 1.2 player alongside the 2004 player, so you generally don’t need to republish. However, if your target LMS has dropped SCORM 1.2 support entirely, you’ll need to republish from the original authoring tool source. There is no reliable automated converter for 1.2-to-2004 that preserves interactivity and tracking behavior.
Q2. How do I preserve historical completion records when the new LMS uses different course identifiers?
This requires a mapping table: source LMS course ID → target LMS course ID. Build this before migration. Most LMS CSV import tools allow you to specify both the course identifier and the completion status independently of the course’s internal ID. Where IDs diverge, the LMS vendor’s professional services team or a custom API script (using the target LMS’s REST API) is usually required. Never assume the new LMS will auto-match courses by title – course titles are not required to be unique in any SCORM specification.
Q3. Should we migrate to xAPI instead of SCORM during an LMS switch?
Only if your new LMS natively supports xAPI alongside a Learning Record Store (LRS), and your authoring tools can publish to xAPI 1.0.3. xAPI is not a drop-in replacement for SCORM in LMS-native delivery – it requires a separate LRS infrastructure (e.g., SCORM Cloud LRS, Learning Locker, watershed) and the content must be republished. For organizations with content that needs to run exclusively inside an LMS with completion/score tracking, SCORM 2004 4th Edition remains the correct choice. xAPI is the right choice when learning data needs to be captured outside the LMS context: mobile apps, simulations, performance support tools, or cross-system analytics pipelines.