apereo/cas · error · FailedLoginException
No password attribute found for
Error message
No password attribute found for
What it means
MongoDbAuthenticationHandler authenticates username/password credentials by looking up the user document in the configured Mongo collection. If the document exists but lacks the configured password attribute field, the handler cannot compare passwords and throws FailedLoginException (authentication fails).
Solutions
- Align cas.authn.mongo[0].password-attribute with the actual field name in your Mongo user documents
- Inspect the user document (db.<collection>.findOne({username: '...'})) and confirm the password field exists and its exact spelling/case
- Fix provisioning/import scripts so every user document includes the password field
- Confirm the query targets the intended collection (cas.authn.mongo[0].collection)
Example fix
// document before
{ "username": "alice", "pwd": "$2a$10$..." }
// after (or set password-attribute=pwd)
{ "username": "alice", "password": "$2a$10$..." } Defensive patterns
Strategy: validation
Validate before calling
// verify the user doc has the password field before expecting login to work
Document user = mongoTemplate.getCollection(collection)
.find(Filters.eq(usernameAttr, username)).first();
if (user == null || !user.containsKey(passwordAttr)) {
throw new IllegalStateException("User doc missing password attribute [" + passwordAttr + "]");
} Try / catch
try {
return authenticationHandler.authenticate(credential);
} catch (FailedLoginException e) {
logger.warn("Login rejected for [{}]: {}", credential.getId(), e.getMessage());
throw e;
} Prevention
- Keep provisioning scripts writing the exact field name configured as password-attribute
- Add a schema check/validator for user documents in the Mongo collection
- Document the expected user document shape alongside CAS config
When it happens
Trigger: cas.authn.mongo[0].password-attribute (default 'password') does not match any field in the user document returned by the query on username-attribute; authenticateUsernamePasswordInternal finds the document via collection.find(Filters.eq(usernameAttribute, username)) but result.containsKey(passwordAttribute) is false.
Common situations: Mongo documents storing the password under a different field name (e.g. 'pass', 'userPassword', 'pwd'); password field accidentally dropped during user provisioning scripts; wrong collection configured so a different schema's document matches; case mismatch between config and field name.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Unable to locate user account
- Authentication handler is disabled
- No user can be accepted because none is defined
- not found in backing map.
- Unable to authenticate
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/89fb2326eb56ce2e.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-mongo/src/main/java/org/apereo/cas/authentication/MongoDbAuthenticationHandler.java:45
public MongoDbAuthenticationHandler(final String name,
final PrincipalFactory principalFactory,
final MongoDbAuthenticationProperties properties,
final MongoOperations mongoTemplate) {
super(name, principalFactory, properties.getOrder());
this.mongoTemplate = mongoTemplate;
this.properties = properties;
}
@Override
protected AuthenticationHandlerExecutionResult authenticateUsernamePasswordInternal(
final UsernamePasswordCredential transformedCredential,
@Nullable final String originalPassword) throws Throwable {
val collection = mongoTemplate.getCollection(properties.getCollection());
try (val it = collection.find(Filters.eq(properties.getUsernameAttribute(), transformedCredential.getUsername())).iterator()) {
if (it.hasNext()) {
val result = it.next();
if (!result.containsKey(properties.getPasswordAttribute())) {
throw new FailedLoginException("No password attribute found for " + transformedCredential.getId());
}
val entryPassword = result.get(properties.getPasswordAttribute());
if (!getPasswordEncoder().matches(originalPassword, entryPassword.toString())) {
LOGGER.warn("Account password on record for [{}] does not match the given/encoded password", transformedCredential.getId());
throw new FailedLoginException();
}
val attributes = result
.entrySet()
.stream()
.filter(entry -> !entry.getKey().equals(properties.getPasswordAttribute()) && !entry.getKey().equals(properties.getUsernameAttribute()))
.collect(Collectors.toMap(Map.Entry::getKey,
entry -> CollectionUtils.toCollection(entry.getValue(), ArrayList.class), (__, b) -> b, () -> new HashMap<String, List<Object>>()));
val principal = this.principalFactory.createPrincipal(transformedCredential.getId(), attributes);
return createHandlerResult(transformedCredential, principal, new ArrayList<>());
}
throw new AccountNotFoundException("Unable to locate user account");
}View on GitHub (pinned to e7288fc434)