{"record":{"id":"b93d61cddf8ae0f1","repo":"apereo/cas","slug":"unknown-duo-security-authentication-attempt","errorCode":null,"errorMessage":"Unknown Duo Security authentication attempt","messagePattern":"Unknown Duo Security authentication attempt","errorType":"exception","errorClass":"FailedLoginException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-duo-core/src/main/java/org/apereo/cas/adaptors/duo/authn/DuoSecurityAuthenticationHandler.java","lineNumber":81,"sourceCode":"     * @return the result of this handler\n     * @throws GeneralSecurityException general security exception for errors\n     */\n    @Override\n    protected AuthenticationHandlerExecutionResult doAuthentication(final Credential credential, final Service service) throws Exception {\n        return switch (credential) {\n            case final DuoSecurityPasscodeCredential duo -> {\n                LOGGER.debug(\"Attempting to authenticate credential via Duo Security passcode\");\n                yield authenticateDuoPasscodeCredential(duo);\n            }\n            case final DuoSecurityUniversalPromptCredential duo -> {\n                LOGGER.debug(\"Attempting to authenticate credential via Duo Security universal prompt\");\n                yield authenticateDuoUniversalPromptCredential(duo);\n            }\n            case final DuoSecurityDirectCredential duo -> {\n                LOGGER.debug(\"Attempting to directly authenticate credential against Duo\");\n                yield authenticateDuoApiCredential(duo);\n            }\n            default -> throw new FailedLoginException(\"Unknown Duo Security authentication attempt\");\n        };\n    }\n\n    /**\n     * Resolve principal.\n     *\n     * @param principal the principal\n     * @return the principal\n     */\n    protected Principal resolvePrincipal(final Principal principal) {\n        return multifactorAuthenticationPrincipalResolver\n            .stream()\n            .filter(resolver -> resolver.supports(principal))\n            .findFirst()\n            .map(resolver -> resolver.resolve(principal))\n            .orElseThrow(() -> new IllegalStateException(\"Unable to resolve principal for Duo Security multifactor authentication\"));\n    }\n","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-duo-core/src/main/java/org/apereo/cas/adaptors/duo/authn/DuoSecurityAuthenticationHandler.java#L63-L99","documentation":"FailedLoginException thrown by DuoSecurityAuthenticationHandler.doAuthentication() when the presented credential is neither a DuoSecurityUniversalPromptCredential nor a DuoSecurityDirectCredential. The handler switches over the credential type and the default branch has no supported path, so it declares the authentication attempt unknown and fails it.","triggerScenarios":"Invoking the Duo handler with any other Credential implementation — e.g. a plain UsernamePasswordCredential routed to the Duo MFA handler, a custom credential class, or a credential that lost its type after serialization/custom flow code.","commonSituations":"See trigger scenarios.","solutions":["Ensure the flow creates and submits the correct credential: DuoSecurityUniversalPromptCredential for the Universal Prompt, or DuoSecurityDirectCredential (e.g. DuoSecurityPasscodeCredential) for direct/API mode.","Review custom webflow actions/configurations that build credentials for the MFA hop and align them with the current CAS Duo credential classes.","Check that only the intended Duo authentication handler handles this credential (authentication policy/selector misrouting another credential type into Duo)."],"exampleFix":"// before\nval credential = new UsernamePasswordCredential(username, pass);\n// after\nval credential = new DuoSecurityDirectCredential(username, passcode);","handlingStrategy":"type-guard","validationCode":"// Before invoking the handler, ensure credential type\nif (!(credential instanceof DuoSecurityUniversalPromptCredential)\n    && !(credential instanceof DuoSecurityDirectCredential)) {\n    throw new IllegalArgumentException(\"Unsupported credential for Duo: \" + credential.getClass());\n}","typeGuard":"boolean isDuoCredential(Credential c) {\n    return c instanceof DuoSecurityUniversalPromptCredential || c instanceof DuoSecurityDirectCredential;\n}","tryCatchPattern":"try {\n    result = duoHandler.authenticate(credential);\n} catch (FailedLoginException e) {\n    LOGGER.error(\"Duo credential type unsupported: {}\", credential.getClass(), e);\n}","preventionTips":["Build MFA flow credentials from the current CAS Duo credential classes only.","After CAS upgrades, re-check custom webflow code that constructs Duo credentials.","Scope Duo handler registration so only Duo credentials route to it."],"tags":["duo","mfa","credential","webflow"],"backgroundTag":"unsupported-operation","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"}