spring-projects/spring-security · error · DisabledException
AccountStatusUserDetailsChecker.disabled
AccountStatusUserDetailsChecker.disabled
Error message
User is disabled
What it means
AccountStatusUserDetailsChecker.check() validates a UserDetails after authentication. When UserDetails.isEnabled() returns false it throws DisabledException with message 'User is disabled'. This indicates the user account exists but is flagged as not enabled.
Source
Thrown at core/src/main/java/org/springframework/security/authentication/AccountStatusUserDetailsChecker.java:51
*
* @author Luke Taylor
*/
public class AccountStatusUserDetailsChecker implements UserDetailsChecker, MessageSourceAware {
private final Log logger = LogFactory.getLog(getClass());
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
@Override
public void check(UserDetails user) {
if (!user.isAccountNonLocked()) {
this.logger.debug("Failed to authenticate since user account is locked");
throw new LockedException(
this.messages.getMessage("AccountStatusUserDetailsChecker.locked", "User account is locked"));
}
if (!user.isEnabled()) {
this.logger.debug("Failed to authenticate since user account is disabled");
throw new DisabledException(
this.messages.getMessage("AccountStatusUserDetailsChecker.disabled", "User is disabled"));
}
if (!user.isAccountNonExpired()) {
this.logger.debug("Failed to authenticate since user account is expired");
throw new AccountExpiredException(
this.messages.getMessage("AccountStatusUserDetailsChecker.expired", "User account has expired"));
}
if (!user.isCredentialsNonExpired()) {
this.logger.debug("Failed to authenticate since user account credentials have expired");
throw new CredentialsExpiredException(this.messages
.getMessage("AccountStatusUserDetailsChecker.credentialsExpired", "User credentials have expired"));
}
}
/**
* Sets the {@link MessageSource} used to resolve exception messages.
* @since 5.2
*/View on GitHub (pinned to 96852e8860)
Solutions
- Enable the account: set the enabled flag to true in your user store or make isEnabled() return true in your UserDetails implementation
- If activation is required, implement an activation flow that flips the enabled flag after verification
- If the flag is loaded incorrectly, fix your UserDetailsService SQL/mapping so the enabled column is read properly
- Catch DisabledException in an AuthenticationFailureHandler and show a 'contact administrator / activate account' message
Example fix
// before
@Override
public boolean isEnabled() { return false; }
// after
@Override
public boolean isEnabled() { return this.enabled; } // persisted activation flag Defensive patterns
Strategy: try-catch
Validate before calling
UserDetails user = uds.loadUserByUsername(username);
if (!user.isEnabled()) { throw new IllegalStateException("Account not activated: " + username); } Type guard
boolean isLoginAllowed(UserDetails u) { return u.isEnabled(); } Try / catch
try { authMgr.authenticate(token); } catch (DisabledException e) { return ResponseEntity.status(403).body("Account is disabled. Please activate or contact support."); } Prevention
- Always persist and load an explicit enabled flag
- Run the account-status checker in tests against representative users
- Catch DisabledException separately from BadCredentialsException for clear UX
When it happens
Trigger: DaoAuthenticationProvider (or any AuthenticationProvider using this checker) authenticates a user whose UserDetails.isEnabled() returns false.
Common situations: Newly registered users whose account requires email activation; admins disabling accounts; user records loaded from a DB column like enabled=0; custom UserDetailsService returning UserDetails with enabled hardcoded false.
Related errors
- User is disabled
- RunAsImplAuthenticationProvider.incorrectKey
- Authenticated principal required to operate with ACLs
- CasAuthenticationProvider.incorrectKey
- oidc_provider_not_configured
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/68193edd01ab3c75.
Report an issue: GitHub.