apereo/cas · warning · AccountDisabledException
Account has been disabled
Error message
Account has been disabled
What it means
QueryDatabaseAuthenticationHandler throws AccountDisabledException('Account has been disabled') when the row's column named by properties.getFieldDisabled() is truthy (BooleanUtils.toBoolean true or '1'). The credential check already passed; the account record is flagged disabled.
Solutions
- Re-enable the account in the database (set the flag to 0/false)
- Verify fieldDisabled maps to the intended status column
- Trace the provisioning job that set the flag if disabling was unexpected
- Update the flag in the system of record so the next sync does not re-disable
Example fix
// before: fieldDisabled bound to always-1 column // cas.authn.jdbc.query[0].fieldDisabled=user_type // after // cas.authn.jdbc.query[0].fieldDisabled=account_disabled
Defensive patterns
Strategy: try-catch
Validate before calling
Map<String,Object> row = jdbc.queryForMap(sql, user);
Object flag = row.get("account_disabled");
boolean disabled = flag != null && ("1".equals(flag.toString()) || BooleanUtils.toBoolean(flag.toString()));
if (disabled) return showAccountDisabledPage(user); Type guard
boolean isTruthyFlag(Object v) { return v != null && ("1".equals(v.toString()) || BooleanUtils.toBoolean(v.toString())); } Try / catch
try {
authResult = handler.authenticate(credential);
} catch (AccountDisabledException e) {
// credentials valid; account administratively disabled
return showAccountDisabledNotice(user);
} Prevention
- Point fieldDisabled at the actual account-status column, never a co-located boolean
- Keep enable/disable state managed in a single system of record
- Audit sync jobs that flip the disabled flag
- Differentiate disabled-vs-expired-vs-wrong-password messages in your flow
When it happens
Trigger: dbFields contains the disabled-field column configured via cas.authn.jdbc.query[0].fieldDisabled and its value parses as a truthy boolean or the string "1".
Common situations: Admin-deactivated accounts, identity/HR sync flagging users, fieldDisabled accidentally mapped to a boolean-ish column that is 1 for all rows (e.g. 'locked' or a type flag).
Related errors
- Account has been disabled
- Password has expired
- Principal attribute [
- [e.getMessage()]
- Password does not match value on record.
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/637d693cf8029368.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-jdbc-authentication/src/main/java/org/apereo/cas/jdbc/QueryDatabaseAuthenticationHandler.java:86
throw new FailedLoginException("Missing field 'total' from the query results for " + username);
}
val count = dbFields.get("total");
if (count == null || !NumberUtils.isCreatable(count.toString())) {
throw new FailedLoginException("Missing field value 'total' from the query results for "
+ username + " or value not parseable as a number");
}
val number = NumberUtils.createNumber(count.toString());
if (number.longValue() != 1) {
throw new FailedLoginException("No records found for user " + username);
}
}
if (StringUtils.isNotBlank(properties.getFieldDisabled()) && dbFields.containsKey(properties.getFieldDisabled())) {
val dbDisabled = dbFields.get(properties.getFieldDisabled()).toString();
if (BooleanUtils.toBoolean(dbDisabled) || "1".equals(dbDisabled)) {
throw new AccountDisabledException("Account has been disabled");
}
}
if (StringUtils.isNotBlank(properties.getFieldExpired()) && dbFields.containsKey(properties.getFieldExpired())) {
val dbExpired = dbFields.get(properties.getFieldExpired()).toString();
if (BooleanUtils.toBoolean(dbExpired) || "1".equals(dbExpired)) {
throw new AccountPasswordMustChangeException("Password has expired");
}
}
val attributes = collectPrincipalAttributes(dbFields);
val principal = this.principalFactory.createPrincipal(username, attributes);
return createHandlerResult(credential, principal, new ArrayList<>());
} catch (final IncorrectResultSizeDataAccessException e) {
if (e.getActualSize() == 0) {
throw new AccountNotFoundException(username + " not found with SQL query");
}
throw new FailedLoginException("Multiple records found for " + username);View on GitHub (pinned to e7288fc434)