apereo/cas · error · BadCredentialsException
Could not authenticate provided credentials
Error message
Could not authenticate provided credentials
What it means
When the LDAP authentication completes without a thrown exception but yields no successful result — no response results, or none containing a resolved entry/authenticated user — the provider throws BadCredentialsException("Could not authenticate provided credentials") as its final statement.
Solutions
- Verify the username exists in LDAP and matches the user filter under the configured base DN
- Double-check the supplied password
- Run ldapsearch with the same base DN and filter to confirm the entry is visible to the bind account
- Confirm the user is not disabled/locked (directories often return no-result style failures)
- Adjust base-dn/user-filter if the entry lives elsewhere
Example fix
// before
// user-filter=(uid={user}) but directory keys on sAMAccountName
// after
// user-filter=(sAMAccountName={user}) Defensive patterns
Strategy: validation
Validate before calling
// confirm the user exists before attempting endpoint auth SearchResult entry = LdapUtils.getLdapEntry(props, "(sAMAccountName=" + user + ")"); boolean userExists = entry != null;
Try / catch
try {
provider.authenticate(token);
} catch (BadCredentialsException e) {
// treat as invalid username/password — do NOT retry, return 401
} Prevention
- Verify usernames and passwords out-of-band with ldapsearch whoami bind tests
- Keep user-filter aligned with the directory naming attribute
- Check the base DN includes the user's OU
- Handle disabled/locked accounts, which often surface as no-results
When it happens
Trigger: authenticate() runs to completion, no Throwable is thrown, but authenticator.authenticate(request) returns a response with zero results (user does not exist, filter does not match) or an unauthenticated result.
Common situations: Typo in username/password for a real user; user does not exist under the configured base DN; user-filter does not match the entry; account exists but bind DN cannot read it; password simply wrong.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Invalid credentials
- Multiple principal values are not allowed: [principalAttr]
- FailedLoginException
- Could not authenticate account for
- Could not authenticate account for
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/5caa54feefca0089.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-ldap-core/src/main/java/org/apereo/cas/authorization/EndpointLdapAuthenticationProvider.java:112
entry.getAttributes().forEach(attribute -> attributes.put(attribute.getName(), new ArrayList<>(attribute.getStringValues())));
val principal = PrincipalFactoryUtils.newPrincipalFactory().createPrincipal(username, attributes);
val authZGen = buildAuthorizationGenerator();
val authorities = authZGen.apply(Objects.requireNonNull(principal));
LOGGER.debug("List of authorities remapped from profile roles are [{}]", authorities);
if (authorities.stream().anyMatch(authority -> requiredRoles.contains(authority.getAuthority()))) {
return generateAuthenticationToken(authentication, authorities);
}
LOGGER.warn("User [{}] is not authorized to access the requested resource", username);
} else {
LOGGER.warn("LDAP authentication response produced no results for [{}]", username);
}
} catch (final Throwable e) {
LoggingUtils.error(LOGGER, e);
throw new InsufficientAuthenticationException("Unexpected LDAP error", e);
}
throw new BadCredentialsException("Could not authenticate provided credentials");
}
@Override
public boolean supports(final Class<?> aClass) {
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(aClass);
}
private Function<Principal, List<SimpleGrantedAuthority>> buildAuthorizationGenerator() {
val properties = ldapProperties.getLdapAuthz();
if (isGroupBasedAuthorization()) {
LOGGER.debug("Handling LDAP authorization based on groups");
return new LdapUserGroupsToRolesAuthorizationGenerator(
ldapAuthorizationGeneratorUserSearchOperation(),
properties.isAllowMultipleResults(),
properties.getGroupAttribute(),
properties.getGroupPrefix(),
ldapAuthorizationGeneratorGroupSearchOperation());View on GitHub (pinned to e7288fc434)