{"record":{"id":"c596574f99cdffd8","repo":"apereo/cas","slug":"invalid-credentials-c59657","errorCode":null,"errorMessage":"Invalid credentials","messagePattern":"Invalid credentials","errorType":"exception","errorClass":"FailedLoginException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-ldap-core/src/main/java/org/apereo/cas/authentication/LdapAuthenticationHandler.java","lineNumber":124,"sourceCode":"        }\n        if (this.principalAttributeMap != null && !this.principalAttributeMap.isEmpty()) {\n            val attrs = this.principalAttributeMap.keySet();\n            attributes.addAll(attrs);\n            LOGGER.debug(\"Configured to retrieve principal attribute collection of [{}]\", attrs);\n        }\n        this.authenticatedEntryAttributes = attributes.toArray(ArrayUtils.EMPTY_STRING_ARRAY);\n        LOGGER.debug(\"LDAP authentication entry attributes for the authentication request are [{}]\", (Object[]) this.authenticatedEntryAttributes);\n    }\n\n    @Override\n    protected AuthenticationHandlerExecutionResult authenticateUsernamePasswordInternal(final UsernamePasswordCredential upc,\n                                                                                        @Nullable final String originalPassword) throws Throwable {\n        val response = getLdapAuthenticationResponse(upc);\n        LOGGER.debug(\"LDAP response: [{}]\", response);\n        if (!passwordPolicyHandlingStrategy.supports(response)) {\n            LOGGER.warn(\"Authentication has failed because LDAP password policy handling strategy [{}] cannot handle [{}].\",\n                response, passwordPolicyHandlingStrategy.getClass().getSimpleName());\n            throw new FailedLoginException(\"Invalid credentials\");\n        }\n        LOGGER.debug(\"Attempting to examine and handle LDAP password policy via [{}]\",\n            passwordPolicyHandlingStrategy.getClass().getSimpleName());\n        val messageList = passwordPolicyHandlingStrategy.handle(response, getPasswordPolicyConfiguration());\n        if (response.isSuccess()) {\n            LOGGER.debug(\"LDAP response returned a result [{}], creating the final LDAP principal\", response.getLdapEntry());\n            val principal = createPrincipal(upc.getUsername(), response.getLdapEntry());\n            return createHandlerResult(upc, principal, messageList);\n        }\n        if (AuthenticationResultCode.DN_RESOLUTION_FAILURE == response.getAuthenticationResultCode()) {\n            LOGGER.warn(\"DN resolution failed. [{}]\", response.getDiagnosticMessage());\n            throw new AccountNotFoundException(upc.getUsername() + \" not found.\");\n        }\n        throw new FailedLoginException(\"Invalid credentials\");\n    }\n\n    /**\n     * Creates a CAS principal with attributes if the LDAP entry contains principal attributes.","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-ldap-core/src/main/java/org/apereo/cas/authentication/LdapAuthenticationHandler.java#L106-L142","documentation":"LdapAuthenticationHandler asks the configured password policy handling strategy whether it can interpret the ldaptive AuthenticationResponse. If strategy.supports(response) is false, the handler gives up and throws FailedLoginException 'Invalid credentials', even though the bind may otherwise have succeeded.","triggerScenarios":"cas.authn.ldap[].passwordPolicyHandlingStrategy is set to a strategy (e.g. GROOWIE, EXTENDED) whose response type does not match the response produced by the configured authenticator/type (AD vs generic LDAP).","commonSituations":"Configuring AD-specific password policy strategy against a non-Active Directory directory; custom authenticator returning responses the strategy cannot parse; copy-pasted LDAP config between server types.","solutions":["Switch passwordPolicyHandlingStrategy to DEFAULT (or the strategy matching your directory, e.g. AD-specific one for Active Directory).","Confirm the ldap authType (AD/DIRECT/BIND/SEARCH) matches the actual directory server.","Check the warning log line naming the unsupported strategy and response to see the mismatch.","Upgrade/align the ldaptive library version so the response type is recognized."],"exampleFix":"// before\ncas.authn.ldap[0].password-policy-strategy= GrooviePasswordPolicyHandlingStrategy\n// after\ncas.authn.ldap[0].password-policy-strategy=DEFAULT","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { result = handler.authenticate(credential); }\ncatch (FailedLoginException e) {\n  if (\"Invalid credentials\".equals(e.getMessage())) { checkLdapPolicyStrategyConfig(); }\n}","preventionTips":["Use the DEFAULT password policy strategy unless you know the directory type.","Keep ldap authType consistent with the server (AD vs generic).","Watch for the 'cannot handle' WARN line when first configuring LDAP."],"tags":["ldap","authentication","password-policy"],"backgroundTag":"ldap-authentication-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"}