apereo/cas · error · AccountNotFoundException
DN resolution failed.
Error message
DN resolution failed. [{}] What it means
CAS's LDAP authentication handler throws AccountNotFoundException when the LDAP authentication result code is DN_RESOLUTION_FAILURE, meaning the directory could not resolve the supplied username to an entry DN. Unlike a wrong password, this means no matching user entry exists under the configured base DNs/search filters. The message logs the server's diagnostic message for details.
Solutions
- Verify the username exists in the directory under the configured baseDn
- Review cas.authn.ldap[0].userFilter / searchFilter and test it directly with ldapsearch for the failing user
- Correct baseDn so the search scope actually contains user accounts
- Check the logged diagnostic message [{}] for the exact filter/DN used
- If users legitimately should not authenticate, handle AccountNotFoundException in the caller rather than changing config
Example fix
// before
cas.authn.ldap[0].userFilter=uid={user},ou=people,dc=example,dc=org
// users actually live under a different OU
// after
cas.authn.ldap[0].baseDn=ou=accounts,dc=example,dc=org
cas.authn.ldap[0].userFilter=(uid={user}) Defensive patterns
Strategy: try-catch
Validate before calling
// Validate the user exists before authenticating, using the same filter String filter = "(uid=" + LdapUtils.encodeLdapFilterValue(username) + ")"; boolean exists = !connection.search(baseDn, SearchScope.SUBTREE, filter).getEntries().isEmpty();
Type guard
if (AuthenticationResultCode.DN_RESOLUTION_FAILURE == response.getAuthenticationResultCode()) {
throw new AccountNotFoundException(username);
} Try / catch
try {
return ldapHandler.authenticate(credential);
} catch (AccountNotFoundException e) {
return AuthenticationResult.UNKNOWN_USER;
} catch (FailedLoginException e) {
return AuthenticationResult.FAILED;
} Prevention
- Keep baseDn and userFilter aligned with the real directory tree; verify with ldapsearch
- Escape/sanitize usernames to avoid filter injection and mismatched matching rules
- Confirm attribute casing (uid vs sAMAccountName) matches your directory schema
- Test a known-good username end-to-end after LDAP config changes
- Return distinct results for unknown-user vs wrong-password in monitoring to spot config drift
When it happens
Trigger: authenticateUsernamePasswordInternal receives a response whose isSuccess() is false and whose getAuthenticationResultCode() equals AuthenticationResultCode.DN_RESOLUTION_FAILURE — i.e. the user search/filter matched no entry, so no DN could be resolved for bind.
Common situations: Typo'd or wrong username; users located outside the configured baseDn; userSearchFilter too restrictive (e.g. extra objectClass conditions the accounts lack); case or attribute mismatch (searching uid vs sAMAccountName); user disabled/removed but credentials cached client-side.
Understand the failure class
Background: "User not found", "Invalid user", and "does not exist": what missing-user lookup errors mean across Rocket.Chat, LiteLLM, Phabricator, rustfs, and pnpm — this error's family across 10 libraries.
Related errors
- [username] not found.
- not found in backing map.
- not found in backing file.
- [username] not found with SQL query.
- Invalid credentials
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/7991c89d6899f7c8.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-ldap-core/src/main/java/org/apereo/cas/authentication/LdapAuthenticationHandler.java:135
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");
}
/**
* Creates a CAS principal with attributes if the LDAP entry contains principal attributes.
*
* @param username Username that was successfully authenticated which is used for principal ID when principal id is not specified.
* @param ldapEntry LDAP entry that may contain principal attributes.
* @return Principal if the LDAP entry contains at least a principal ID attribute value.
* @throws LoginException On security policy errors related to principal creation.
*/
protected @Nullable Principal createPrincipal(final String username, final LdapEntry ldapEntry) throws Throwable {
LOGGER.debug("Creating LDAP principal for [{}] based on [{}] and attributes [{}]", username, ldapEntry.getDn(),
ldapEntry.getAttributeNames());
val id = getLdapPrincipalIdentifier(username, ldapEntry);
LOGGER.debug("LDAP principal identifier created is [{}]", id);View on GitHub (pinned to e7288fc434)