LifterLMS Mark Complete Not Working? Why Lessons Will Not Complete

Diagnose a LifterLMS lesson that will not mark complete: quiz and assignment requirements, minimum lesson time, cached pages with expired security tokens, JavaScript conflicts and enrollment, with a symptom table and a way to complete the lesson for a stuck student.

  • Add as a preferred source on Google
Illustration for “LifterLMS Mark Complete Not Working? Why Lessons Will Not Complete”

A student clicks Mark Complete and nothing happens. Or the button is greyed out, or missing, or the next lesson opens but the last one is still not ticked. When LifterLMS mark complete is not working, the cause is nearly always one of a handful of rules or conflicts, and most of them can be identified in a few minutes.

This guide explains what happens when the button is clicked, then works through each cause by the symptom it produces. It also shows how to complete a lesson for a stuck student while you fix the underlying problem, and includes a small logging snippet for developers.

What happens when a student clicks Mark Complete

The button submits a small form back to the lesson page. On the server, LifterLMS then runs three checks in order:

  1. The security token. The form carries a WordPress nonce. If it is missing or expired, LifterLMS ignores the submission completely, with no message.
  2. Permission. The student must be enrolled in the lesson's course and the lesson must be available to them. If not, they see "You are not allowed to complete this lesson."
  3. Completion rules. LifterLMS asks whether completion is allowed. Core uses this to enforce quiz requirements and minimum lesson time, and add-ons such as Assignments hook into the same check. If any rule says no, the lesson simply is not completed.

Then, by default, LifterLMS redirects to the next lesson. That redirect happens whether or not step 3 allowed completion. This is why a student can end up on lesson 4 with lesson 3 still incomplete, and why "it moved on but didn't save" is a symptom of a rule blocking completion rather than a database fault.

Diagnose by symptom

What the student seesLook at first
No Mark Complete button, a Take Quiz button insteadA quiz is attached to the lesson
No button at allNot enrolled, lesson not yet available, or a page builder template missing the button
Button visible but greyed outMinimum lesson time still running, or JavaScript not running
Click reloads the page and nothing changesCached page with an expired security token
Next lesson opens, previous lesson not tickedA completion rule blocked it: quiz, minimum time or an add-on
"You are not allowed to complete this lesson."Enrollment, expired access, drip or prerequisite
Lesson ticked, but progress or course completion looks wrongCaching of progress or a completion requirement elsewhere in the course

Quiz and assignment requirements

When a lesson has a published quiz, the Mark Complete button is replaced by Take Quiz, and finishing the quiz is what completes the lesson. Two settings decide what counts:

  • With the lesson's Require Passing Grade setting on, only a passing attempt completes the lesson.
  • With it off, any finished attempt completes it, but at least one attempt is still required.

So a student who failed a required quiz cannot complete the lesson by any button. They need another attempt, or you need to review the quiz settings. Our guide to creating quizzes in LifterLMS covers attempts and passing grades, and an unpublished quiz is ignored entirely.

The paid Assignments add-on works the same way: a lesson with an assignment is completed through the assignment, by submitting it or by passing it, depending on how it is set up. If a student says they submitted but the lesson is incomplete, check the assignment's status and grading settings in that add-on.

Minimum lesson time

Since version 10.1, a lesson can require a minimum time before it can be completed, using the Enable Minimum Time setting with hours, minutes and seconds. While the time is running, the Mark Complete and Take Quiz buttons are disabled in the page markup, and a timer shows progress.

How it counts matters when troubleshooting:

  • Time is recorded on the server through a heartbeat sent from the browser every 30 seconds by default. The button is enabled when the server confirms the time is met, not when the on-screen clock says so.
  • The student must stay logged in. If their session expires, the timer stops and they are asked to log in again.
  • One timed lesson per student at a time. Opening the same lesson, or another timed lesson, in a second tab supersedes the first session, and the original tab asks the student to reload.
  • Closing the tab pauses the clock. Time resumes from where it stopped on return.

Version 10.1.1 fixed a case where clicking at the exact moment the time was reached was rejected, so update if you are on 10.1.0. Our article on LifterLMS lesson time tracking covers the setting in depth, and the official lesson time tracking documentation describes how the timer pauses and resumes.

Caching and expired security tokens

If the page reloads and nothing changes, suspect caching first. The Mark Complete form contains a nonce that WordPress generates for the logged-in user and that expires after a day or so. A page cache that serves a stored copy of the lesson to a logged-in student hands them someone else's or yesterday's token, and LifterLMS silently discards the submission.

The same problem breaks the lesson timer, which needs a fresh token for its heartbeat. Typical culprits are server-level or CDN "cache everything" rules that ignore WordPress login cookies, and caching plugins configured to cache pages for logged-in users.

The fix is to never serve cached HTML to logged-in users on course, lesson and quiz pages. Our guide to configuring caching for LifterLMS has the exclusion rules for common caching layers.

JavaScript errors and theme or builder conflicts

Several parts of the lesson page depend on JavaScript: the minimum time timer that enables the button, the quiz interface, and some add-on requirements. If scripts fail, buttons stay disabled forever.

  1. Open the lesson as a student, then open the browser's developer console. Red errors point at the script that broke.
  2. If you use a performance plugin, temporarily turn off JavaScript combining, deferring and "delay until user interaction". A disabled button that is waiting for a script that never runs looks exactly like a LifterLMS fault.
  3. Switch to a default theme on a staging copy and retest. If the button returns, the theme or a template override is the cause.
  4. With page builders, check that the lesson template actually includes LifterLMS's lesson progression element. A custom lesson layout without it shows no button at all.
  5. Deactivate other plugins one at a time on staging to find a conflict.

Enrollment, access and admin testing

"You are not allowed to complete this lesson" means the permission check failed: the student is not enrolled in the course, their access has expired or been cancelled, or the lesson is not yet available because of drip or a prerequisite. Our guide to diagnosing course access problems walks through each of those.

Be careful testing as an administrator. Users who can edit the lesson are always allowed to complete it, so an admin test hides permission problems. Use a real test student account.

If the lesson is complete but the student says their progress bar is wrong, check for page caching first, then for completion requirements elsewhere: a course is only complete when every lesson is.

Complete the lesson for a stuck student

While you fix the cause, you can unblock a student from the admin:

  1. Go to LifterLMS > Reporting > Students and open the student.
  2. Open their Courses tab and click the course.
  3. Use the Mark Complete action on the lesson.

An admin completion overrides minimum time, which is recorded as an override. It does not override quiz requirements: the action is hidden for a lesson whose quiz the student has not yet satisfied.

For developers, this snippet logs every blocked completion with the lesson, user and trigger, so you can see which rule is saying no. It runs after core's own checks, and the entries appear under LifterLMS > Status > Logs:

<?php
add_filter( 'llms_allow_lesson_completion', 'llmsx_log_blocked_completion', 999, 5 );
function llmsx_log_blocked_completion( $allow, $user_id, $lesson_id, $trigger, $args ) {
	if ( ! $allow ) {
		llms_log(
			sprintf( 'Completion blocked: lesson #%d, user #%d, trigger "%s"', $lesson_id, $user_id, $trigger ),
			'lesson-completion'
		);
	}
	return $allow;
}

Frequently asked questions

Why is the Mark Complete button missing in LifterLMS?

Usually because the lesson has a quiz, which replaces it with Take Quiz. Otherwise the student is not enrolled, the lesson is not yet available, or your theme or page builder template does not output the button.

Why is the Mark Complete button greyed out?

The lesson has a minimum time that has not been met, or the JavaScript that enables the button is not running. Check the timer and the browser console.

Can students mark a lesson incomplete?

Only if Retake Lessons is enabled under LifterLMS > Settings > Courses. Administrators can always mark a lesson incomplete from the student's course report.

Why does it work for me but not for students?

Administrators bypass permission checks and are rarely served cached pages. Test with a real student account in a private browser window.

What to do next

Match the symptom in the table, check that one cause, and retest as a real student. If you cannot reproduce the problem, add the logging snippet and wait for the next report; the trigger and lesson ID usually point straight at the rule involved.

If completion rules, caching and add-ons are tangled together on your site, our LifterLMS support team can find the conflict on a staging copy. Send us the lesson URL and what the student sees.

Add LifterLMS Expert to your preferred sources

Add lifterlmsexpert as a preferred source on Google, or open this article in your AI assistant to use it as a source.

  • Add as a preferred source on Google
Free consultation

Prefer expert help over DIY?

Skip the trial and error. Get specialist LifterLMS help and ship faster.

Talk to a LifterLMS Expert Explore our services

Replies within one business day