apereo/cas · error · FailedLoginException
Account password on file does not match the provided…
Error message
Account password on file does not match the provided password for [{}] What it means
JsonResourceAuthenticationHandler authenticates users from a JSON resource map of username to account. When the submitted password does not match the stored hash/password for the located username, it logs this warning and throws FailedLoginException, resulting in an authentication failure for the user.
Solutions
- Verify the user is typing the correct password; reset it in the JSON resource if needed
- Confirm the password format in the JSON matches the configured PasswordEncoder (e.g. SHA/BCrypt vs plaintext)
- Regenerate the stored hash after any password-encoder change
- Check that the JSON resource path points to the intended environment's file
Example fix
// before
{"admin": {"password": "plaintext", "status": "OK"}}
// after (with BCrypt encoder configured)
{"admin": {"password": "$2a$10$N9qo8uLOickgx2ZMRZoMye...", "status": "OK"}} Defensive patterns
Strategy: validation
Validate before calling
var account = userMap.get(username);
if (account == null) throw new AccountNotFoundException();
if (!passwordEncoder.matches(rawPassword, account.getPassword())) {
LOGGER.warn("password mismatch for {}", username);
} Try / catch
try {
handler.authenticate(transaction);
} catch (FailedLoginException e) {
handleBadPassword(username);
} catch (AccountDisabledException e) {
handleDisabled(username);
} Prevention
- Keep password hashes in the JSON file consistent with the configured PasswordEncoder
- Regenerate hashes after any encoder change
- Point environments at the correct JSON resource and version-control it
When it happens
Trigger: authenticateUsernamePasswordInternal finds the username in the JSON map, but matches(originalPassword, account.getPassword()) returns false - wrong password typed, stale JSON data, or mismatched password-encoder configuration.
Common situations: User typo or forgotten password; JSON file edited by hand with plaintext while the handler expects an encoded password (or vice versa); PasswordEncoder changed in config but JSON data not migrated; wrong JSON resource loaded in the target environment.
Related errors
- Invalid credentials:
- Unable to accept cookie for authentication
- Unable to login from this location
- Unable to login at this time
- Cannot validate authentication for: [login]
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/a03960257e337285.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-generic/src/main/java/org/apereo/cas/adaptors/generic/JsonResourceAuthenticationHandler.java:68
super(name, principalFactory, order);
this.resource = resource;
}
@Override
protected AuthenticationHandlerExecutionResult authenticateUsernamePasswordInternal(
final UsernamePasswordCredential credential, final String originalPassword) throws Throwable {
val map = readAccountsFromResource();
val username = credential.getUsername();
LOGGER.debug("Attempting to authenticate [{}]", username);
if (!map.containsKey(username)) {
LOGGER.debug("Unable to locate user account for [{}]", username);
throw new AccountNotFoundException();
}
val account = map.get(username);
if (!matches(originalPassword, account.getPassword())) {
LOGGER.warn("Account password on file does not match the provided password for [{}]", username);
throw new FailedLoginException();
}
LOGGER.debug("Located account [{}]", account);
switch (account.getStatus()) {
case DISABLED -> throw new AccountDisabledException();
case EXPIRED -> throw new AccountExpiredException();
case LOCKED -> throw new AccountLockedException();
case MUST_CHANGE_PASSWORD -> throw new AccountPasswordMustChangeException();
case OK -> LOGGER.debug("Account status is OK");
}
val clientInfo = ClientInfoHolder.getClientInfo();
if (clientInfo != null && StringUtils.isNotBlank(account.getLocation())
&& !RegexUtils.find(account.getLocation(), clientInfo.getClientIpAddress())) {
throw new InvalidLoginLocationException("Unable to login from this location");
}
View on GitHub (pinned to e7288fc434)