apereo/cas · error · FailedLoginException
Authentication has failed because LDAP password policy…
Error message
Authentication has failed because LDAP password policy handling strategy [{}] cannot handle [{}]. What it means
This error is thrown by CAS's LDAP authentication handler when the configured password policy handling strategy does not support the LdapAuthenticationResponse returned by the directory. The strategy (e.g. GNUPasswordPolicy, ActiveDirectory) can only interpret specific response/controls; when it cannot handle the response, CAS treats the attempt as a failed login and throws FailedLoginException. It usually signals a mismatch between the directory type and the configured passwordPolicyHandlingStrategy.
Solutions
- Set the password policy type (cas.authn.ldap[0].password-policy.type) to a strategy matching your directory (AD, FreeIPA, GNU, or default/custom)
- Enable the password policy request control on the LDAP connection (enablePasswordPolicyControls / connection pool controls) so the response carries data the strategy supports
- Inspect the logged 'LDAP response: [{}]' debug line to see what the response actually contains and adjust the strategy accordingly
- If policy handling is not needed, use the default strategy that accepts any response
- Update any custom PasswordPolicyHandlingStrategy so supports() matches the response types your server returns
Example fix
// before cas.authn.ldap[0].password-policy.type=ActiveDirectory // against OpenLDAP // after cas.authn.ldap[0].password-policy.type=GNU cas.authn.ldap[0].password-policy.warning-attribute-display=false
Defensive patterns
Strategy: validation
Validate before calling
// Pre-check strategy/response compatibility before login attempts
if (!ldapPasswordPolicyStrategy.supports(response)) {
LOGGER.warn("Strategy {} cannot handle response {}; reconfigure cas.authn.ldap[0].password-policy.type",
ldapPasswordPolicyStrategy.getClass().getSimpleName(), response.getAuthenticationResultCode());
} Type guard
if (response != null && passwordPolicyHandlingStrategy.supports(response)) {
// safe to call handle()
} Try / catch
try {
return handler.authenticate(credential);
} catch (FailedLoginException e) {
LOGGER.warn("LDAP login rejected: {} — verify password-policy strategy matches directory controls", e.getMessage());
return AuthenticationResult.FAILED;
} Prevention
- Match the configured password-policy.type to the actual directory server (AD vs OpenLDAP vs FreeIPA)
- Enable the password policy request control on the LDAP connection
- Test the strategy with a known-bad password and a known-good password in staging
- Log the raw LDAP response at debug level when troubleshooting
- Write a unit test asserting supports() returns true for your server's response type
When it happens
Trigger: A login attempt reaches LdapAuthenticationHandler.authenticateUsernamePasswordInternal, getLdapAuthenticationResponse returns a response, and passwordPolicyHandlingStrategy.supports(response) returns false — e.g. strategy set to a specific policy type while the bind result carries no policy request/response controls, or using the GNU/AD strategy against a directory that returns none of the expected controls.
Common situations: Setting cas.authn.ldap[0].password-policy.type to an ActiveDirectory-specific strategy while authenticating against OpenLDAP (or vice versa); customizing the strategy class whose supports() rejects null/empty responses; LDAP server upgraded and stopped returning password-policy controls; strategy misconfigured for the authentication method (anonymous bind vs password comparison).
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Invalid credentials
- Multiple principal values are not allowed: [principalAttr]
- No user can be accepted because none is defined
- Unable to authenticate
- Principal id attribute is not found for [principalAttr]
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/646c91bb014825cc.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-ldap-core/src/main/java/org/apereo/cas/authentication/LdapAuthenticationHandler.java:122
LOGGER.debug("Configured to retrieve principal id attribute [{}]", this.principalIdAttribute);
attributes.add(this.principalIdAttribute);
}
if (this.principalAttributeMap != null && !this.principalAttributeMap.isEmpty()) {
val attrs = this.principalAttributeMap.keySet();
attributes.addAll(attrs);
LOGGER.debug("Configured to retrieve principal attribute collection of [{}]", attrs);
}
this.authenticatedEntryAttributes = attributes.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
LOGGER.debug("LDAP authentication entry attributes for the authentication request are [{}]", (Object[]) this.authenticatedEntryAttributes);
}
@Override
protected AuthenticationHandlerExecutionResult authenticateUsernamePasswordInternal(final UsernamePasswordCredential upc,
@Nullable final String originalPassword) throws Throwable {
val response = getLdapAuthenticationResponse(upc);
LOGGER.debug("LDAP response: [{}]", response);
if (!passwordPolicyHandlingStrategy.supports(response)) {
LOGGER.warn("Authentication has failed because LDAP password policy handling strategy [{}] cannot handle [{}].",
response, passwordPolicyHandlingStrategy.getClass().getSimpleName());
throw new FailedLoginException("Invalid credentials");
}
LOGGER.debug("Attempting to examine and handle LDAP password policy via [{}]",
passwordPolicyHandlingStrategy.getClass().getSimpleName());
val messageList = passwordPolicyHandlingStrategy.handle(response, getPasswordPolicyConfiguration());
if (response.isSuccess()) {
LOGGER.debug("LDAP response returned a result [{}], creating the final LDAP principal", response.getLdapEntry());
val principal = createPrincipal(upc.getUsername(), response.getLdapEntry());
return createHandlerResult(upc, principal, messageList);
}
if (AuthenticationResultCode.DN_RESOLUTION_FAILURE == response.getAuthenticationResultCode()) {
LOGGER.warn("DN resolution failed. [{}]", response.getDiagnosticMessage());
throw new AccountNotFoundException(upc.getUsername() + " not found.");
}
throw new FailedLoginException("Invalid credentials");
}
View on GitHub (pinned to e7288fc434)