{"record":{"id":"934fb319bc348f92","repo":"apereo/cas","slug":"failed-to-authenticate-code-934fb3","errorCode":null,"errorMessage":"Failed to authenticate code ","messagePattern":"Failed to authenticate code ","errorType":"exception","errorClass":"MultifactorAuthenticationFailedException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-simple-mfa-core/src/main/java/org/apereo/cas/mfa/simple/CasSimpleMultifactorAuthenticationHandler.java","lineNumber":75,"sourceCode":"    @Override\n    public boolean supports(final Class<? extends Credential> clazz) {\n        return CasSimpleMultifactorTokenCredential.class.isAssignableFrom(clazz);\n    }\n\n    @Override\n    protected AuthenticationHandlerExecutionResult doAuthentication(final Credential credential,\n                                                                    final Service service) throws Exception {\n        return FunctionUtils.doAndThrow(() -> {\n            val tokenCredential = (CasSimpleMultifactorTokenCredential) credential;\n            val credentialPrincipal = multifactorAuthenticationService.fetch(tokenCredential);\n            val resolvedPrincipal = resolvePrincipal(applicationContext, credentialPrincipal);\n            val principal = multifactorAuthenticationService.validate(resolvedPrincipal, tokenCredential);\n\n            val activePrincipal = findActivePrincipal();\n            if (!principal.equals(activePrincipal)) {\n                LOGGER.warn(\"Credential principal [{}] does not match authentication principal [{}]\",\n                    principal.getId(), activePrincipal.getId());\n                throw new MultifactorAuthenticationFailedException(\"Failed to authenticate code \" + tokenCredential.getId());\n            }\n            return createHandlerResult(tokenCredential, principal);\n        }, MultifactorAuthenticationFailedException::new);\n    }\n\n    protected Principal findActivePrincipal() {\n        val authentication = Objects.requireNonNull(WebUtils.getInProgressAuthentication());\n        val principal = authentication.getPrincipal();\n        return principal.getOwner();\n    }\n}\n","sourceCodeStart":57,"sourceCodeEnd":87,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-simple-mfa-core/src/main/java/org/apereo/cas/mfa/simple/CasSimpleMultifactorAuthenticationHandler.java#L57-L87","documentation":"CasSimpleMultifactorAuthenticationHandler.doAuthentication validates the MFA token credential against the simple MFA service and then compares the token's principal with the currently active authentication principal. On any validation failure or mismatch, it throws MultifactorAuthenticationFailedException \"Failed to authenticate code <id>\". It means the supplied one-time MFA code/ticket is not usable for this authentication attempt.","triggerScenarios":"doAuthentication -> multifactorAuthenticationService.validate(...) throwing (missing principal on ticket, principal mismatch, throttled attempts) or the returned principal not equaling findActivePrincipal(), e.g. the code was issued to a different user or was already consumed/expired.","commonSituations":"User submits an expired or already-used MFA code; code generated in one browser/session but submitted from another login (principal mismatch); clustered deployments where the ticket registry is not shared so the token cannot be found; throttling after repeated wrong codes.","solutions":["Request and submit a fresh MFA code within its validity window in the same session","Ensure the same authenticated principal completes the MFA step (no account switch mid-flow)","Verify all CAS nodes share the same ticket registry so tokens issued on one node validate on another","Check throttling configuration/bucket limits if users are being locked out by retry volume"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    handlerResult = authenticationHandler.authenticate(transaction);\n} catch (MultifactorAuthenticationFailedException e) {\n    // discard the stale/foreign code and re-enter the MFA flow to get a fresh one\n    mfaRelayService.requestNewCode(activePrincipal);\n}","preventionTips":["Submit MFA codes promptly; they are one-time and short-lived","Complete the whole login (primary + MFA) in one session and browser","Ensure clustered CAS nodes share one ticket registry (e.g. Redis/Hazelcast)"],"tags":["mfa","authentication","one-time-token","principal-mismatch"],"backgroundTag":"mfa-code-validation-failed","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"}