LearnDash Lesson Not Completing After SCORM or xAPI? 4 Causes and Fixes

LearnDash Lesson Not Completing

Your learner finishes lesson 1, moves on to lesson 2, and works through the xAPI module or quiz. The content says “Module complete” or “Passed”. But the lesson still says In Progress, the course is stuck at 50%, and lesson 3 won’t open.

From the learner’s side, they did everything right. From your side, something between the content and LearnDash didn’t hand the completion on. This guide shows how to find that something in a couple of minutes with GrassBlade’s Completion Testing Tool, then walks through the four causes behind most of these tickets. We set each one up on a demo site with a test learner, Jordan, so every screenshot below is a real result.

How a completion reaches LearnDash

Two systems are involved. Your WordPress site runs LearnDash and GrassBlade xAPI Companion, which plays the xAPI, SCORM or cmi5 content inside the lesson. GrassBlade LRS is separate: it stores every statement the content sends. A completion travels like this:

  1. The content, running in the lesson on WordPress, sends a “completed” or “passed” statement to GrassBlade LRS when its own rule is met.
  2. GrassBlade LRS stores it, and a completion trigger sends it back to your WordPress site.
  3. GrassBlade xAPI Companion checks the content’s settings, such as Completion Tracking.
  4. LearnDash marks the lesson, topic or quiz complete.

If any link breaks, the learner sees the content finish and the lesson stay open.

Start here: run the Completion Testing Tool

Before changing settings, test the setup for the learner who reported the problem. The Completion Testing Tool runs the checks a support engineer would otherwise do by hand.

Step 1: Open the learner’s profile. In WP Admin, go to Users and edit the learner. Near the end of the profile, under GrassBlade: Test Completion Tracking, click Start Testing.

Step 2: Pick the content. The tool opens over the profile. In Content, choose the xAPI Content the learner is stuck on, then click Start Testing again. Don’t click Restart Content for this User; it resets the learner’s attempt.

Step 3: Read the checks from the top. The tool runs each check in order and marks it Passed or Failed:

CheckWhat it tells you
1. Completion Tracking is enabled?Whether the content is allowed to complete lessons at all
2. Multiple Contents with Same Activity IDWhether two contents are fighting over one completion
3. Content Added on & CompletionWhere the content is used, and whether this learner completed those steps
4. LMS CheckWhether the LMS integration is in place
5. Completion Triggers in GrassBlade LRSWhether the LRS will pass completions back to WordPress
6. Statement TestWhether the LRS has a completed or passed statement from this learner
7. Error Log TestWhat happened in WordPress when the completion arrived
8. GrassBlade Email TestWhether the learner’s email belongs to exactly one user

Step 4: Open the blue ⓘ next to anything that fails. Every check, and every trigger inside check 5, has a blue info icon. Click it and a panel opens with four parts: About, Reason for Failure, Impact and Solution. Several include a button that takes you straight to the fix, such as Go to Edit Page or Go to Triggers. Read it before you change anything else.

You can also open the tool from the content: WP Admin > xAPI Content > edit the content > Test Completion Tracking, then enter the learner’s email, user ID or username.

Here’s how the four cases look in the tool:

CaseWhat fails in the tool
1. Completion Tracking is offCheck 1
2. Completion triggers missingCheck 5 (Passed, Failed, Completed triggers)
3. Quiz pass marks don’t matchNothing fails; the check 7 Error Log entry shows it
4. The completion never reaches the LRSCheck 6, the Statement Test

Case 1: Completion Tracking is turned off

What the learner sees. Jordan finishes the module and it says “Module complete”, but lesson 2 still says In Progress. Look at the top bar: the Mark Complete button is there from the moment the lesson opens, before Jordan has even started the module. Nothing ties the lesson to the content. Many learners don’t click it, because they expect the lesson to complete itself, and the ones who do click it can complete the lesson without opening the module.

What the tool shows. Check 1, Completion Tracking is enabled?, fails. Everything else passes, including the triggers and Jordan’s completion statement.

The ⓘ panel names the cause (“The Completion Tracking option box is not checked in the xAPI Content edit page”) and gives the fix, with a Go to Edit Page button.

The fix. Edit the content (WP Admin > xAPI Content) and, in xAPI Content Details:

  • Tick Completion Tracking and save. Without it, GrassBlade records the learner’s activity but never asks LearnDash to complete the lesson. This is the fix.
  • Completion Type is a separate setting. It only controls LearnDash’s Mark Complete button; it doesn’t decide whether the lesson completes. The default is Hide Button. Set it to suit your course:
    • Hide Button (default): no button; the lesson completes automatically when the content does.
    • Show button on completion: the button appears once the content is completed.
    • Enable button on completion: the button is visible but disabled until the completion arrives. While you’re testing, this shows you the moment the completion comes through.
    • Auto-redirect on completion: completes the lesson and moves the learner to the next step.

Learners who already finished don’t have to redo the content. Run the testing tool for them again. When the Statement Test lists their completions with a Re-Trigger Completion button, click it. On our demo it returned “Success”, and LearnDash marked Jordan’s lesson 2 complete straight away.

Case 2: The completion triggers were never created

What the learner sees. This is the frustrating one. Jordan finishes the module, and lesson 2 stays In Progress. With Completion Type set to Hide Button there’s no Mark Complete button either, so Jordan is stuck with no way forward.

What the tool shows. Check 5, Completion Triggers in GrassBlade LRS, fails. The Attempted trigger exists, but the Passed, Failed and Completed triggers are missing. Check 6 passes: the LRS did receive Jordan’s completion. It just had no trigger to send it back to WordPress.

Click the ⓘ next to a missing trigger. The panel lists the exact trigger to create (name, type, URL, verb, status) and has a Go to Triggers button.

The fix. In GrassBlade LRS, open Triggers and click Add New for each missing trigger, using the settings from the panel: type Completion, the URL of your WordPress site’s admin-ajax.php?action=grassblade_completion_tracking, and status ON. Create one each for completed, passed and failed. When they’re right, the Triggers page shows a green banner saying the Completion Triggers for your WordPress website are configured correctly.

Learn more: Completion Tracking

If the triggers exist but point at an old domain or a staging site, the result is the same. Edit the URL. From then on, completions go through. For a learner who finished while the triggers were missing, use Re-Trigger Completion if the Statement Test shows the button, or ask them to finish the content once more.

Case 3: The quiz says “Passed”, LearnDash says no

This one catches experienced site owners, because GrassBlade and LearnDash each judge the score against their own passing percentage.

Our lesson 2 has a LearnDash quiz with xAPI content inside it:

  • The LearnDash quiz has a Passing Score of 80%.
  • The xAPI Content has a Passing Percentage of 50%. This field is optional, and many sites leave it empty. We filled it in to show what happens when the two disagree.

What the learner sees. Jordan answers 2 of 3 questions correctly (67%). The content says “Passed”, and the results table under it shows Status: Passed. But the sidebar still shows lesson 2 and its quiz open, and the course stays at 50%.

What happened: GrassBlade compared 67% with the content’s 50% and recorded Passed. LearnDash compared the same 67% with the quiz’s 80% and recorded a failed quiz attempt. A failed quiz doesn’t complete the lesson.

What the tool shows. Every check passes, so read the Error Log Test. Its entry spells it out: Status (67 >= 50.00): Passed, then grassblade_learndash_quiz_completion Status (67 >= 80): Failed.

The fix. Make the pass marks agree:

  • LearnDash: edit the quiz, open Settings, and set Passing Score under Progression and Restriction Settings. This is the pass mark that completes the lesson.
  • GrassBlade: Passing Percentage on the xAPI Content is optional. Leave it empty, or set it to the same number as the quiz.

Also check the pass mark set in your authoring tool when you published the package. Ours tells learners “You need 2 correct (67%) to pass”, so it said “Passed” too. When all three numbers agree, learners never see “Passed” on a quiz that LearnDash failed.

A learner whose attempt was already recorded as failed needs a new attempt after the change. GrassBlade won’t record the same statement against the quiz twice.

Case 4: The completion never reaches the LRS

This one happens even when everything above is set up correctly, which makes it the most common case on a working site.

What the learner sees. The same as case 2: they reach the end, and lesson 2 stays In Progress.

What the tool shows. Check 5 passes, so the triggers are fine. Check 6, the Statement Test, fails: there’s no completed or passed statement in the LRS for this learner and this content.

The Statement Test’s ⓘ panel names the first thing to check: the learner didn’t finish all the steps of the content. These are the usual reasons the completion never arrives, and what to do about each:

WhyWhat to do
The learner didn’t complete every step the content requiresAsk them to finish all the steps. Check your authoring tool’s completion rule if you’re not sure what counts.
A workplace firewall or proxy blocked the content from reaching the LRSWhitelist your LRS address on that network. The data never reached the LRS, so the learner needs to complete the content again.
The network dropped while the content was sendingThe learner completes the content again on a stable connection.

When the statement is in the LRS but the lesson still didn’t complete, the Statement Test passes and the Error Log Test shows the trigger failing. Here, a firewall or security plugin on your WordPress site blocked the trigger the LRS sent back. Whitelist your LRS in that plugin or firewall, then click Re-Trigger Completion in the Statement Test. The learner doesn’t need to redo anything.

On our demo, we showed this case with a learner who never finished the module, so no statement reached the LRS. We didn’t reproduce the firewall and network causes; they produce the same result in the tool.

Quick reference: what the learner sees, and where to look

What the learner seesCheck that fails in the testing toolFix
Content finished, lesson In Progress, Mark Complete shown before the content even starts1. Completion Tracking is enabled?Tick Completion Tracking (Case 1)
Content finished, lesson In Progress, no Mark Complete button5. Completion Triggers in GrassBlade LRSCreate the completed, passed and failed triggers (Case 2)
Content says Passed, quiz and lesson stay openNone; read the 7. Error Log entryUse the quiz Passing Score as the pass mark; leave the content Passing Percentage empty or set it to match (Case 3)
Learner finished, lesson In Progress, triggers fine6. Statement TestNot every step finished, or a firewall or network drop stopped it. Fix the cause, complete the content again (Case 4)
Statement is in the LRS, Error Log shows the trigger failing7. Error Log TestWhitelist the LRS in your WordPress security plugin or firewall, then Re-Trigger Completion (Case 4)
Not sure which it isRun all checks, open the ⓘ for any that failFollow that panel’s Solution

FAQ

Why does GrassBlade show “Passed” when LearnDash says the quiz failed?
They used different pass marks. GrassBlade’s reports use the xAPI Content’s Passing Percentage when you’ve set one. LearnDash uses the quiz’s Passing Score. Leave the content’s field empty, or set it to the same number.

The learner says they finished, but the LRS has nothing. What happened?
The completion never reached the LRS. Usually the learner skipped a step the content requires, or a workplace firewall or a network drop stopped the data. Fix the cause, then have them complete the content again (Case 4).

Do learners have to redo the content after I fix a setting?
Not always. After you turn on Completion Tracking or add the triggers, run the testing tool for the learner. If the Statement Test shows Re-Trigger Completion, click it and the lesson completes. For a failed quiz attempt, the learner needs a new attempt.

Why is Mark Complete showing before the learner has even started?
Completion Tracking is off for that content, so GrassBlade leaves LearnDash’s button alone. Turn tracking on. The Completion Type then decides how the button behaves (Hide Button by default).

What do the blue icons in the testing tool do?
Each opens a panel explaining that check: what it tests, the common reasons it fails, the impact, and the solution, often with a button to the right settings page.

Which testing-tool options change a learner’s data?
Restart Content for This User resets the learner’s attempt, and Re-Trigger Completion re-sends a completion to WordPress. The checks themselves only read.

Still stuck?

The Completion Testing Tool guide explains every check. Our Completion Tracking Not Working checklist covers the less common causes, such as Activity ID changes, re-uploaded packages and connection tests. To see it all working, try the GrassBlade demo, or read how to add xAPI, SCORM and cmi5 content to LearnDash.

Leave a Comment

Your email address will not be published. Required fields are marked *

Shopping Cart
Scroll to Top
We are making major changes on payment options & license management. Please, click here to report any issues you face during the purchase.