{"record":{"id":"3593228c002c2313","repo":"theonedev/onedev","slug":"cannot-reset-two-factor-authentication-for-disable","errorCode":null,"errorMessage":"Cannot reset two factor authentication for disabled account","messagePattern":"Cannot reset two factor authentication for disabled account","errorType":"http","errorClass":"ExplicitException","httpStatus":400,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/rest/resource/UserResource.java","lineNumber":545,"sourceCode":"\t\t} else if (user.equals(getAuthUser())) {\n\t\t\tuser.setAiSetting(aiSetting);\n\t\t\tuserService.update(user, null);\n\t\t\treturn Response.ok().build();\n    \t} else {\n\t\t\tthrow new UnauthorizedException();\n\t\t}\n    }\n\n\t@Api(order=2025)\n\t@Path(\"/{userId}/two-factor-authentication\")\n\t@DELETE\n\tpublic Response resetTwoFactorAuthentication(@PathParam(\"userId\") Long userId) {\n\t\tif (!SecurityUtils.isAdministrator()) \n\t\t\tthrow new UnauthorizedException();\n\n\t\tUser user = userService.load(userId);\t\t\n\t\tif (user.isDisabled()) {\n\t\t\tthrow new ExplicitException(\"Cannot reset two factor authentication for disabled account\");\n\t\t} else if (user.getType() != ORDINARY) {\n\t\t\tthrow new ExplicitException(\"Cannot reset two factor authentication for service or AI account\");\n\t\t} else {\n\t\t\tuser.setTwoFactorAuthentication(null);\n\t\t\tuserService.update(user, null);\n\t\t\tauditService.audit(null, \"reset two factor authentication of account \\\"\" + user.getName() + \"\\\" via RESTful API\", null, null);\n\t\t\treturn Response.ok().build();\n\t\t}\n\t}\n\t\n\t@Api(order=2100)\n\t@Path(\"/{userId}/queries-and-watches\")\n    @POST\n    public Response setQueriesAndWatches(@PathParam(\"userId\") Long userId, @NotNull QueriesAndWatches queriesAndWatches) {\n    \tUser user = userService.load(userId);\n    \tif (!SecurityUtils.isAdministrator() && !user.equals(getAuthUser())) \n\t\t\tthrow new UnauthorizedException();\n","sourceCodeStart":527,"sourceCodeEnd":563,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/rest/resource/UserResource.java#L527-L563","documentation":"The resetTwoFactorAuthentication endpoint (POST /users/{userId}/reset-two-factor-authentication) refuses to operate on disabled accounts. Clearing a user's 2FA configuration is only permitted for active accounts, since a disabled account cannot authenticate and resetting its 2FA has no legitimate workflow.","triggerScenarios":"Calling POST /rest/v1/users/{userId}/reset-two-factor-authentication as administrator for a user whose account is disabled.","commonSituations":"Helpdesk clearing 2FA for a locked-out user whose account was also disabled; bulk security resets touching suspended accounts; cleanup scripts resetting 2FA for all users.","solutions":["Re-enable the account first, then reset two-factor authentication","Skip disabled accounts in bulk 2FA reset scripts","Confirm the user's enabled state via GET /users/{userId} before resetting 2FA"],"exampleFix":"// before\nawait rest.post(`/users/${id}/reset-two-factor-authentication`); // fails if disabled\n// after\nconst user = await rest.get(`/users/${id}`);\nif (!user.disabled) {\n  await rest.post(`/users/${id}/reset-two-factor-authentication`);\n}","handlingStrategy":"validation","validationCode":"const user = await rest.get(`/users/${userId}`); if (user.disabled) throw new Error('Cannot reset 2FA for a disabled account');","typeGuard":"function canReset2fa(user) { return !user.disabled && user.type === 'ORDINARY'; }","tryCatchPattern":"try { await rest.post(`/users/${id}/reset-two-factor-authentication`); } catch (e) { if (e.status === 400 && /disabled account/.test(e.message)) { /* re-enable first */ } else throw e; }","preventionTips":["Verify the account is active before 2FA resets","Re-enable accounts before clearing their 2FA","Exclude disabled accounts from bulk security resets"],"tags":["rest-api","two-factor-authentication","disabled-account","onedev"],"backgroundTag":"invalid-state-transition","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"}