apereo/cas · warning · AccountDisabledException

Account has been disabled

Error message

Account has been disabled

What it means

The handler throws AccountDisabledException('Account has been disabled') when the row returned by the SQL query has a truthy value in the column named by properties.getDisabledFieldName(). Authentication stops even though the password was correct, because the account record is administratively disabled.

Solutions

  1. Re-enable the account in the source database (set flag to 0/false)
  2. Verify disabledFieldName maps to the correct schema column
  3. Check upstream provisioning/identity sync that may have disabled the user
  4. If the flag is stale, correct it in the user-management system of record

Example fix

// before: points at 'locked' tinyint that is always 1
// cas.authn.jdbc.encode[0].fieldDisabled=locked
// after
// cas.authn.jdbc.encode[0].fieldDisabled=account_disabled
Defensive patterns

Strategy: try-catch

Validate before calling

boolean disabled = jdbc.queryForObject("SELECT account_disabled FROM users WHERE username=?", Boolean.class, user);
if (disabled) return accountDisabledPage(user);

Try / catch

try {
    authResult = handler.authenticate(credential);
} catch (AccountDisabledException e) {
    // valid credentials but deactivated account
    return showAccountDisabledNotice(user);
}

Prevention

When it happens

Trigger: Query result contains the disabled-field column whose value is BooleanUtils.toBoolean(...) true or the string "1".

Common situations: Admin deactivated the account (locked, leave of absence, terminated), HR/identity sync set the flag, disabledFieldName accidentally mapped to a column that is 1 for all users.

Related errors


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

Appendix: source

Thrown at support/cas-server-support-jdbc-authentication/src/main/java/org/apereo/cas/jdbc/QueryAndEncodeDatabaseAuthenticationHandler.java:69

        final UsernamePasswordCredential transformedCredential, final String originalPassword) throws Throwable {
        val username = transformedCredential.getUsername();
        try {
            val sqlQueryResults = performSqlQuery(username);
            val digestedPassword = databasePasswordEncoder.encode(transformedCredential.toPassword(), sqlQueryResults);

            if (!sqlQueryResults.get(properties.getPasswordFieldName()).equals(digestedPassword)) {
                throw new FailedLoginException("Password does not match value on record.");
            }
            if (StringUtils.isNotBlank(properties.getExpiredFieldName()) && sqlQueryResults.containsKey(properties.getExpiredFieldName())) {
                val dbExpired = sqlQueryResults.get(properties.getExpiredFieldName()).toString();
                if (BooleanUtils.toBoolean(dbExpired) || "1".equals(dbExpired)) {
                    throw new AccountPasswordMustChangeException("Password has expired");
                }
            }
            if (StringUtils.isNotBlank(properties.getDisabledFieldName()) && sqlQueryResults.containsKey(properties.getDisabledFieldName())) {
                val dbDisabled = sqlQueryResults.get(properties.getDisabledFieldName()).toString();
                if (BooleanUtils.toBoolean(dbDisabled) || "1".equals(dbDisabled)) {
                    throw new AccountDisabledException("Account has been disabled");
                }
            }
            val attributes = collectPrincipalAttributes(sqlQueryResults);
            val principal = principalFactory.createPrincipal(username, attributes);
            return createHandlerResult(transformedCredential, 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);
        } catch (final DataAccessException e) {
            throw new PreventedException(e);
        }
    }

    protected Map<String, Object> performSqlQuery(final String username) {
        return getJdbcTemplate().queryForMap(properties.getSql(), username);
    }

View on GitHub (pinned to e7288fc434)