spring-projects/spring-security · error · DisabledException

User is disabled

Error message

User is disabled

What it means

DefaultPreAuthenticationChecks.check() in AbstractUserDetailsAuthenticationProvider throws DisabledException 'User is disabled' when UserDetails.isEnabled() returns false. The username/password matched but the account is not enabled for login.

Source

Thrown at core/src/main/java/org/springframework/security/authentication/dao/AbstractUserDetailsAuthenticationProvider.java:379

	public void setAuthoritiesMapper(GrantedAuthoritiesMapper authoritiesMapper) {
		this.authoritiesMapper = authoritiesMapper;
	}

	private class DefaultPreAuthenticationChecks implements UserDetailsChecker {

		@Override
		public void check(UserDetails user) {
			if (!user.isAccountNonLocked()) {
				AbstractUserDetailsAuthenticationProvider.this.logger
					.debug("Failed to authenticate since user account is locked");
				throw new LockedException(AbstractUserDetailsAuthenticationProvider.this.messages
					.getMessage("AbstractUserDetailsAuthenticationProvider.locked", "User account is locked"));
			}
			if (!user.isEnabled()) {
				AbstractUserDetailsAuthenticationProvider.this.logger
					.debug("Failed to authenticate since user account is disabled");
				throw new DisabledException(AbstractUserDetailsAuthenticationProvider.this.messages
					.getMessage("AbstractUserDetailsAuthenticationProvider.disabled", "User is disabled"));
			}
			if (!user.isAccountNonExpired()) {
				AbstractUserDetailsAuthenticationProvider.this.logger
					.debug("Failed to authenticate since user account has expired");
				throw new AccountExpiredException(AbstractUserDetailsAuthenticationProvider.this.messages
					.getMessage("AbstractUserDetailsAuthenticationProvider.expired", "User account has expired"));
			}
		}

	}

	private class DefaultPostAuthenticationChecks implements UserDetailsChecker {

		@Override
		public void check(UserDetails user) {
			if (!user.isCredentialsNonExpired()) {
				AbstractUserDetailsAuthenticationProvider.this.logger

View on GitHub (pinned to 96852e8860)

Solutions

  1. Enable the account in the user store or fix isEnabled() in your UserDetails implementation
  2. Implement the account-activation step (email confirmation) that flips enabled to true
  3. Fix UserDetailsService mapping if the enabled flag is misread
  4. Handle DisabledException in an AuthenticationFailureHandler to guide users to activation

Example fix

// before
return new User(username, password, true, true, true, false, authorities); // enabled=false in 4th-true/false group? ensure correct position
// after
return User.withUsername(username).password(password).disabled(false).accountLocked(false).authorities(authorities).build();
Defensive patterns

Strategy: try-catch

Validate before calling

UserDetails user = uds.loadUserByUsername(username);
if (!user.isEnabled()) { throw new IllegalStateException("Account not enabled: " + 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."); }

Prevention

When it happens

Trigger: DaoAuthenticationProvider pre-authentication check on a UserDetails with isEnabled() == false.

Common situations: Unactivated registrations; admin-disabled users; UserDetailsService mapping the enabled column incorrectly; custom UserDetails with enabled hardcoded false.

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/c9680a9a193f1c52. Report an issue: GitHub.