{"record":{"id":"d36a4745791c8990","repo":"apereo/cas","slug":"captcha-value-does-not-match-or-cas-cannot-unlock","errorCode":null,"errorMessage":"Captcha value does not match, or CAS cannot unlock the account for ","messagePattern":"Captcha value does not match, or CAS cannot unlock the account for ","errorType":"exception","errorClass":"AccountLockedException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-pm-webflow/src/main/java/org/apereo/cas/pm/web/flow/actions/AccountUnlockStatusAction.java","lineNumber":37,"sourceCode":" * @author Misagh Moayyed\n * @since 6.6.0\n */\n@Slf4j\n@RequiredArgsConstructor\npublic class AccountUnlockStatusAction extends BaseCasWebflowAction {\n\n    private final PasswordManagementService passwordManagementService;\n\n    @Override\n    protected @Nullable Event doExecuteInternal(final RequestContext requestContext) {\n        try {\n            val credential = requestContext.getConversationScope().get(Credential.class.getName(), Credential.class);\n            LOGGER.debug(\"Attempting to unlock account for [{}]\", credential);\n            val givenValue = requestContext.getConversationScope().get(\"captchaValue\", String.class);\n            val providedValue = WebUtils.getRequestParameterOrAttribute(requestContext, \"captchaValue\").orElseThrow();\n            LOGGER.debug(\"Comparing captcha value [{}] with user entry [{}]\", givenValue, providedValue);\n            if (!givenValue.equals(providedValue) || !passwordManagementService.unlockAccount(credential)) {\n                throw new AccountLockedException(\"Captcha value does not match, or CAS cannot unlock the account for \" + credential.getId());\n            }\n            WebUtils.addInfoMessageToContext(requestContext, \"screen.account.unlock.success\");\n            return success();\n        } catch (final Throwable e) {\n            WebUtils.addErrorMessageToContext(requestContext, \"screen.account.unlock.fail\");\n            LoggingUtils.error(LOGGER, e);\n            return error();\n        }\n    }\n}\n","sourceCodeStart":19,"sourceCodeEnd":48,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-pm-webflow/src/main/java/org/apereo/cas/pm/web/flow/actions/AccountUnlockStatusAction.java#L19-L48","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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."],"exampleFix":"// before\nif (!givenValue.equals(providedValue) || !passwordManagementService.unlockAccount(credential)) { throw ... }\n// after (captive, case-insensitive compare)\nif (!StringUtils.equalsIgnoreCase(givenValue, providedValue) || !passwordManagementService.unlockAccount(credential)) { throw ... }","handlingStrategy":"validation","validationCode":"// Pre-check captcha and unlock eligibility\nif (!Objects.equals(givenCaptcha, providedCaptcha)) { return error(\"captcha mismatch\"); }\nif (!pmService.isAccountLocked(credential)) { return error(\"account is not locked\"); }","typeGuard":null,"tryCatchPattern":"try { unlockStatusAction.execute(ctx); } catch (AccountLockedException e) { WebUtils.addErrorMessageToContext(ctx, \"screen.account.unlock.fail\"); }","preventionTips":["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."],"tags":["captcha","account-locked","password-management"],"backgroundTag":"invalid-argument-value","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}