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

  1. Align cas.authn.mongo[0].password-attribute with the actual field name in your Mongo user documents
  2. Inspect the user document (db.<collection>.findOne({username: '...'})) and confirm the password field exists and its exact spelling/case
  3. Fix provisioning/import scripts so every user document includes the password field
  4. 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

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


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)