spring-projects/spring-security · warning · LockedException
${ex.getStatus().getDefaultMessage()}
Error message
${ex.getStatus().getDefaultMessage()} What it means
LdapAuthenticationProvider.doAuthentication() converts a PasswordPolicyException from the authenticator into a LockedException whose message is the password-policy status default message (e.g. 'account is locked', resolved via messages.getMessage(ex.getStatus().getErrorCode(), ...)). This indicates the LDAP password policy response reported a problem, most commonly a locked account during a bind.
Source
Thrown at ldap/src/main/java/org/springframework/security/ldap/authentication/LdapAuthenticationProvider.java:179
}
protected LdapAuthoritiesPopulator getAuthoritiesPopulator() {
return this.authoritiesPopulator;
}
public void setHideUserNotFoundExceptions(boolean hideUserNotFoundExceptions) {
this.hideUserNotFoundExceptions = hideUserNotFoundExceptions;
}
@Override
protected DirContextOperations doAuthentication(UsernamePasswordAuthenticationToken authentication) {
try {
return getAuthenticator().authenticate(authentication);
}
catch (PasswordPolicyException ex) {
// The only reason a ppolicy exception can occur during a bind is that the
// account is locked.
throw new LockedException(
this.messages.getMessage(ex.getStatus().getErrorCode(), ex.getStatus().getDefaultMessage()));
}
catch (UsernameNotFoundException ex) {
if (this.hideUserNotFoundExceptions) {
throw new BadCredentialsException(
this.messages.getMessage("LdapAuthenticationProvider.badCredentials", "Bad credentials"));
}
throw ex;
}
catch (NamingException ex) {
throw new InternalAuthenticationServiceException(ex.getMessage(), ex);
}
}
@Override
protected Collection<? extends GrantedAuthority> loadUserAuthorities(DirContextOperations userData, String username,
String password) {
return getAuthoritiesPopulator().getGrantedAuthorities(userData, username);View on GitHub (pinned to 96852e8860)
Solutions
- Unlock the account in the directory (e.g. reset pwdAccountLockedTime in OpenLDAP or unlock in AD).
- Reduce lockout pressure: add rate limiting/account lockout backoff on your login endpoint.
- Tell the user their account is locked rather than a generic bad-credentials message.
- Review password policy settings (lockout duration/threshold) if lockouts are too aggressive.
- Verify ppolicy overlay/control is configured consistently between the app and the directory.
Example fix
// before
try {
authManager.authenticate(token);
} catch (LockedException e) {
log.error("login failed"); // losing the lock info
}
// after
try {
authManager.authenticate(token);
} catch (LockedException e) {
auditLog.record("ACCOUNT_LOCKED", username);
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Your account is locked. Contact support.");
} Defensive patterns
Strategy: try-catch
Try / catch
try {
authManager.authenticate(token);
} catch (LockedException e) {
audit.record("ACCOUNT_LOCKED", token.getName());
throw new ResponseStatusException(HttpStatus.LOCKED, "account is locked; contact your administrator");
} Prevention
- Add rate limiting/backoff to the login endpoint to avoid triggering pwdLockout.
- Surface lockout distinctly to users so they contact support instead of retrying.
- Monitor pwdAccountLockedTime events from the directory.
- Align app ppolicy controls with directory policy configuration.
When it happens
Trigger: The configured authenticator (BindAuthenticator with ppolicy control support) throws PasswordPolicyException; doAuthentication maps it to LockedException with ex.getStatus().getDefaultMessage(). Occurs when the directory's password policy control reports the account is locked (too many failed attempts, admin lock, or expired password policies).
Common situations: User exceeded the directory's failed-attempt threshold and was auto-locked, administrator manually locked the account, OpenLDAP ppolicy pwdLockout triggered, or repeated automated login attempts from a misbehaving client.
Related errors
- <namingException.getMessage()>
- ${ctrl.getErrorStatus()}
- AbstractUserDetailsAuthenticationProvider.locked
- AbstractUserDetailsAuthenticationProvider.credentialsExpired
- AccountStatusUserDetailsChecker.locked
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/ae129c2e516b689d.
Report an issue: GitHub.