{"record":{"id":"78cb35bbc9273be3","repo":"spring-projects/spring-security","slug":"user-account-is-locked","errorCode":null,"errorMessage":"User account is locked","messagePattern":"User account is locked","errorType":"exception","errorClass":"LockedException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/springframework/security/authentication/dao/AbstractUserDetailsAuthenticationProvider.java","lineNumber":373,"sourceCode":"\t * @param alwaysPerformAdditionalChecksOnUser\n\t * @since 5.7.23\n\t */\n\tpublic void setAlwaysPerformAdditionalChecksOnUser(boolean alwaysPerformAdditionalChecksOnUser) {\n\t\tthis.alwaysPerformAdditionalChecksOnUser = alwaysPerformAdditionalChecksOnUser;\n\t}\n\n\tpublic void setAuthoritiesMapper(GrantedAuthoritiesMapper authoritiesMapper) {\n\t\tthis.authoritiesMapper = authoritiesMapper;\n\t}\n\n\tprivate class DefaultPreAuthenticationChecks implements UserDetailsChecker {\n\n\t\t@Override\n\t\tpublic void check(UserDetails user) {\n\t\t\tif (!user.isAccountNonLocked()) {\n\t\t\t\tAbstractUserDetailsAuthenticationProvider.this.logger\n\t\t\t\t\t.debug(\"Failed to authenticate since user account is locked\");\n\t\t\t\tthrow new LockedException(AbstractUserDetailsAuthenticationProvider.this.messages\n\t\t\t\t\t.getMessage(\"AbstractUserDetailsAuthenticationProvider.locked\", \"User account is locked\"));\n\t\t\t}\n\t\t\tif (!user.isEnabled()) {\n\t\t\t\tAbstractUserDetailsAuthenticationProvider.this.logger\n\t\t\t\t\t.debug(\"Failed to authenticate since user account is disabled\");\n\t\t\t\tthrow new DisabledException(AbstractUserDetailsAuthenticationProvider.this.messages\n\t\t\t\t\t.getMessage(\"AbstractUserDetailsAuthenticationProvider.disabled\", \"User is disabled\"));\n\t\t\t}\n\t\t\tif (!user.isAccountNonExpired()) {\n\t\t\t\tAbstractUserDetailsAuthenticationProvider.this.logger\n\t\t\t\t\t.debug(\"Failed to authenticate since user account has expired\");\n\t\t\t\tthrow new AccountExpiredException(AbstractUserDetailsAuthenticationProvider.this.messages\n\t\t\t\t\t.getMessage(\"AbstractUserDetailsAuthenticationProvider.expired\", \"User account has expired\"));\n\t\t\t}\n\t\t}\n\n\t}\n","sourceCodeStart":355,"sourceCodeEnd":391,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/core/src/main/java/org/springframework/security/authentication/dao/AbstractUserDetailsAuthenticationProvider.java#L355-L391","documentation":"The DefaultPreAuthenticationChecks.check() in AbstractUserDetailsAuthenticationProvider throws LockedException 'User account is locked' when UserDetails.isAccountNonLocked() returns false. Authentication is rejected because the account is administratively or automatically locked.","triggerScenarios":"DaoAuthenticationProvider post-load validation of a UserDetails whose isAccountNonLocked() returns false.","commonSituations":"Too many failed login attempts triggering an account-lockout service (e.g. Spring Security's own lockout implementations or a DB lock_flag); admin-locked accounts; UserDetails returning isAccountNonLocked=false by mistake.","solutions":["Unlock the account in your user store (clear the locked flag / lock timestamp)","If lockout is automatic, wait out the lock duration or provide an unlock/reset flow","If you don't use account locking, return true from isAccountNonLocked() in your UserDetails","Catch LockedException in the failure handler and tell the user why login failed and how to unlock"],"exampleFix":"// before\nUPDATE users SET locked = true WHERE username = ?;\n// after\nUPDATE users SET locked = false, failed_attempts = 0 WHERE username = ?;","handlingStrategy":"try-catch","validationCode":"UserDetails user = uds.loadUserByUsername(username);\nif (!user.isAccountNonLocked()) { throw new IllegalStateException(\"Account locked: \" + username); }","typeGuard":"boolean isLoginAllowed(UserDetails u) { return u.isAccountNonLocked(); }","tryCatchPattern":"try { authMgr.authenticate(token); } catch (LockedException e) { return ResponseEntity.status(423).body(\"Account locked. Unlock or wait for lockout to expire.\"); }","preventionTips":["Implement lockout with an explicit unlock mechanism and clear messaging","Reset failed-attempt counters on successful login","If locking is unused, always return true from isAccountNonLocked()"],"tags":["spring-security","authentication","account-locked"],"backgroundTag":"authentication-required","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}