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
- Verify the user is submitting the correct credentials.
- Align cas.authn.password-encoder.type/encoding with how passwords are stored in Cassandra (e.g. bcrypt vs plaintext).
- Re-hash or correct the stored password for the account if it was seeded manually.
- 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
- Ensure the configured password encoder type matches how passwords are stored/hashed in Cassandra.
- Validate seeded account hashes with a known-good password in an integration test.
- Audit stored password values for whitespace, prefixes, or stale formats after migrations.
- Provide clear user feedback distinguishing unknown account from bad password where policy allows.
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
- Unable to find account
- Account password on record for
- Authentication handler is disabled
- No user can be accepted because none is defined
- not found in backing map.
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)