apereo/cas · error · AccountLockedException
Captcha value does not match, or CAS cannot unlock the…
Error message
Captcha value does not match, or CAS cannot unlock the account for
What it means
AccountLockedException thrown by AccountUnlockStatusAction when either the captcha value entered by the user does not equal the captcha value stored in conversation scope, or the PasswordManagementService.unlockAccount call returns false. Both conditions must succeed for the account unlock to proceed.
Solutions
- Restart the unlock flow so a fresh captcha is generated, and enter it exactly as shown (comparison is case-sensitive equals).
- Check the configured PasswordManagementService (e.g. LDAP/JDBC PM handler) actually supports unlocking and the account exists in the backend.
- Verify session/conversation state is preserved (no load-balancer dropping sticky sessions, cookies enabled).
- Inspect the error logged by LoggingUtils to distinguish captcha mismatch from unlockAccount returning false.
Example fix
// before
if (!givenValue.equals(providedValue) || !passwordManagementService.unlockAccount(credential)) { throw ... }
// after (captive, case-insensitive compare)
if (!StringUtils.equalsIgnoreCase(givenValue, providedValue) || !passwordManagementService.unlockAccount(credential)) { throw ... } Defensive patterns
Strategy: validation
Validate before calling
// Pre-check captcha and unlock eligibility
if (!Objects.equals(givenCaptcha, providedCaptcha)) { return error("captcha mismatch"); }
if (!pmService.isAccountLocked(credential)) { return error("account is not locked"); } Try / catch
try { unlockStatusAction.execute(ctx); } catch (AccountLockedException e) { WebUtils.addErrorMessageToContext(ctx, "screen.account.unlock.fail"); } Prevention
- Keep the unlock flow within one conversation; warn users about session timeouts.
- Match captcha entry exactly (case-sensitive); avoid ambiguous glyphs in the captcha image.
- Verify the backing PM service supports unlocking for your account store.
When it happens
Trigger: During the password-management account-unlock flow, the request parameter captchaValue differs from the conversation-scoped captchaValue, or passwordManagementService.unlockAccount(credential) reports the account could not be unlocked.
Common situations: User mistypes the captcha (case-sensitive comparison); captcha expired because the conversation scope was lost (session timeout, new browser window); the backing account store rejects the unlock (user not found, account not lockable via the configured PM service).
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- AccountLockedException
- Could not authenticate locked account for
- No registered devices for multifactor authentication could…
- No security questions could be found for
- Recaptcha score received is less than the threshold score…
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/d36a4745791c8990.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-pm-webflow/src/main/java/org/apereo/cas/pm/web/flow/actions/AccountUnlockStatusAction.java:37
* @author Misagh Moayyed
* @since 6.6.0
*/
@Slf4j
@RequiredArgsConstructor
public class AccountUnlockStatusAction extends BaseCasWebflowAction {
private final PasswordManagementService passwordManagementService;
@Override
protected @Nullable Event doExecuteInternal(final RequestContext requestContext) {
try {
val credential = requestContext.getConversationScope().get(Credential.class.getName(), Credential.class);
LOGGER.debug("Attempting to unlock account for [{}]", credential);
val givenValue = requestContext.getConversationScope().get("captchaValue", String.class);
val providedValue = WebUtils.getRequestParameterOrAttribute(requestContext, "captchaValue").orElseThrow();
LOGGER.debug("Comparing captcha value [{}] with user entry [{}]", givenValue, providedValue);
if (!givenValue.equals(providedValue) || !passwordManagementService.unlockAccount(credential)) {
throw new AccountLockedException("Captcha value does not match, or CAS cannot unlock the account for " + credential.getId());
}
WebUtils.addInfoMessageToContext(requestContext, "screen.account.unlock.success");
return success();
} catch (final Throwable e) {
WebUtils.addErrorMessageToContext(requestContext, "screen.account.unlock.fail");
LoggingUtils.error(LOGGER, e);
return error();
}
}
}
View on GitHub (pinned to e7288fc434)