apereo/cas · error · FailedLoginException

Account password on record for

Error message

Account password on record for [{}] does not match the given password

What it means

CassandraAuthenticationHandler logs this warning when the stored password attribute for the user does not match the presented credential after encoding/matching via getPasswordEncoder().matches(). It throws FailedLoginException, meaning the account exists but the password is wrong.

Solutions

  1. Verify the user is submitting the correct credentials.
  2. Align cas.authn.password-encoder.type/encoding with how passwords are stored in Cassandra (e.g. bcrypt vs plaintext).
  3. Re-hash or correct the stored password for the account if it was seeded manually.
  4. Inspect the stored value format (trailing whitespace, algorithm prefix) and normalize it.

Example fix

// before: stored plaintext, encoder mismatch
cas.authn.password-encoder.type=BCRYPT
// after: matches plaintext storage
cas.authn.password-encoder.type=NONE
cas.authn.password-encoder.encoding=UTF-8
Defensive patterns

Strategy: try-catch

Validate before calling

// sanity-check encoder vs storage before enabling handler
if (encoder.getType() != storedHashScheme) {
  throw new IllegalStateException("password encoder mismatch: " + encoder.getType());
}

Try / catch

try {
  return handler.authenticateUsernamePasswordInternal(credential);
} catch (FailedLoginException e) {
  LOGGER.warn("Bad password for [{}] (encoder={})", credential.getUsername(), encoderType);
  return AuthenticationHandlerResult.badPassword(credential);
}

Prevention

When it happens

Trigger: authenticateUsernamePasswordInternal retrieves the entry password from the configured password attribute and passwordEncoder.matches(originalPassword, entryPassword) returns false.

Common situations: User typed a wrong password; stored hash was generated with a different encoding/algorithm than the configured password encoder (e.g. plain vs bcrypt); password changed upstream but stale in Cassandra; password attribute column contains extra whitespace or a prefix/salt format the encoder does not expect.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/f16de2fa80970a36. Report an issue: GitHub.

Appendix: source

Thrown at support/cas-server-support-cassandra-authentication/src/main/java/org/apereo/cas/authentication/CassandraAuthenticationHandler.java:50

    @Override
    protected AuthenticationHandlerExecutionResult authenticateUsernamePasswordInternal(final UsernamePasswordCredential credential,
                                                                                        @Nullable final String originalPassword) throws Throwable {
        val username = credential.getUsername();
        val attributes = this.cassandraRepository.getUser(username);

        if (attributes == null || attributes.isEmpty()
            || !attributes.containsKey(cassandraAuthenticationProperties.getUsernameAttribute())
            || !attributes.containsKey(cassandraAuthenticationProperties.getPasswordAttribute())) {
            LOGGER.warn("Unable to find account [{}]: The account does not exist or it's missing username/password attributes", username);
            throw new AccountNotFoundException();
        }

        LOGGER.debug("Located account attributes [{}] for [{}]", attributes.keySet(), username);
        val entryPassword = attributes.get(cassandraAuthenticationProperties.getPasswordAttribute()).getFirst().toString();

        if (!getPasswordEncoder().matches(originalPassword, entryPassword)) {
            LOGGER.warn("Account password on record for [{}] does not match the given password", username);
            throw new FailedLoginException();
        }
        val principal = this.principalFactory.createPrincipal(username, attributes);
        return createHandlerResult(credential, principal, new ArrayList<>());
    }
}

View on GitHub (pinned to e7288fc434)