{"record":{"id":"333375f7c32109b9","repo":"theonedev/onedev","slug":"account-is-disabled","errorCode":null,"errorMessage":"Account is disabled","messagePattern":"Account is disabled","errorType":"exception","errorClass":"DisabledAccountException","httpStatus":null,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/security/DefaultAuthenticatingService.java","lineNumber":143,"sourceCode":"\t\t\temailAddress.setVerificationCode(null);\n\t\t\tuser.addEmailAddress(emailAddress);\n\t\t\temailAddressService.create(emailAddress);\n\t\t}\n\t\tsyncGroupsAndSshKeys(user, false, authenticated, defaultGroupName);\n\t}\n\t\n\t@Override\n\tprotected final AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) \n\t\t\tthrows AuthenticationException {\n\t\treturn transactionService.call(() -> {\n\t\t\ttry {\n\t\t\t\tvar userName = normalizeUserName((String) token.getPrincipal());\n\t\t\t\tvar user = userService.findByVerifiedEmailAddress((String) token.getPrincipal());\n\t\t\t\tif (user == null) \n\t\t\t\t\tuser = userService.findByName(userName);\n\t\t\t\tif (user != null) {\n\t\t\t\t\tif (user.isDisabled())\n\t\t\t\t\t\tthrow new DisabledAccountException(_T(\"Account is disabled\"));\n\t\t\t\t\telse if (user.getType() != ORDINARY)\n\t\t\t\t\t\tthrow new DisabledAccountException(_T(\"Service or AI account not allowed to login\"));\n\t\t\t\t\tif (user.getPassword() == null) {\n\t\t\t\t\t\tvar authenticator = settingService.getAuthenticator();\n\t\t\t\t\t\tif (authenticator != null) {\n\t\t\t\t\t\t\tvar authenticated = authenticator.authenticate((UsernamePasswordToken) token);\n\t\t\t\t\t\t\tvar emailAddressValue = authenticated.getEmail();\n\t\t\t\t\t\t\tif (emailAddressValue != null) {\n\t\t\t\t\t\t\t\tvar emailAddress = emailAddressService.findByValue(emailAddressValue);\n\t\t\t\t\t\t\t\tif (emailAddress != null) {\n\t\t\t\t\t\t\t\t\tif (emailAddress.getOwner().equals(user) || !emailAddress.isVerified()) {\n\t\t\t\t\t\t\t\t\t\tupdateUser(user, authenticated, emailAddress, authenticator.getDefaultGroup());\n\t\t\t\t\t\t\t\t\t\treturn user;\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tthrow new AuthenticationException(MessageFormat.format(_T(\"Email address \\\"{0}\\\" already used by another account\"), emailAddressValue));\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tupdateUser(user, authenticated, null, authenticator.getDefaultGroup());","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/security/DefaultAuthenticatingService.java#L125-L161","documentation":"OneDev's AuthenticatingRealm (doGetAuthenticationInfo in DefaultAuthenticatingService) resolves the user by email or name during username/password login. If the resolved user has the 'disabled' flag set, authentication is aborted with a Shiro DisabledAccountException so no session is created. This is a deliberate policy check, not a bug: disabled users must not be able to authenticate even with valid credentials.","triggerScenarios":"A login attempt (UsernamePasswordToken) via the web sign-in form, REST basic auth, or git credential auth where userService.findByVerifiedEmailAddress/findByName returns a user whose User.isDisabled() is true.","commonSituations":"An administrator disabled the account (e.g. offboarding a user or suspending an account for policy reasons) while the user still has stored credentials; CI jobs or git clients using that user's token/password suddenly fail with this message.","solutions":["Have a OneDev administrator re-enable the account: Server Administration -> Users, select the user and clear the disabled setting.","If the account was disabled intentionally, switch automated clients to a different account or a service/access token of an enabled user.","Verify you are authenticating as the intended user (email vs name normalization may resolve an unexpected disabled account).","If the user should only lose UI access, consider permission-group restrictions instead of disabling, so integrations keep working."],"exampleFix":"// before (admin keeps account disabled; job fails)\ngit clone http://disabled-user@onedev.example.com/project.git\n// after (admin re-enables the user in Administration -> Users)\ngit clone http://enabled-user@onedev.example.com/project.git","handlingStrategy":"try-catch","validationCode":"// Before relying on a login, check the account state via API (admin):\nUser u = userService.findByName(name);\nif (u != null && u.isDisabled()) { /* prompt admin to re-enable */ }","typeGuard":"function canLogin(user) { return user != null && !user.isDisabled() && user.type === 'ORDINARY'; }","tryCatchPattern":"try {\n  authenticate(username, password);\n} catch (DisabledAccountException e) {\n  logger.warn(\"Login rejected: account disabled - contact admin\");\n}","preventionTips":["Notify credential owners before disabling accounts and migrate their integrations first.","Audit stored credentials/tokens periodically for disabled users.","Use groups/permissions instead of full disable when only limited access removal is needed."],"tags":["authentication","user-management","security"],"backgroundTag":"account-disabled","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}