theonedev/onedev · error · ExplicitException

Cannot reset two factor authentication for disabled account

Error message

Cannot reset two factor authentication for disabled account

What it means

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.

Source

Thrown at server-core/src/main/java/io/onedev/server/rest/resource/UserResource.java:545

		} else if (user.equals(getAuthUser())) {
			user.setAiSetting(aiSetting);
			userService.update(user, null);
			return Response.ok().build();
    	} else {
			throw new UnauthorizedException();
		}
    }

	@Api(order=2025)
	@Path("/{userId}/two-factor-authentication")
	@DELETE
	public Response resetTwoFactorAuthentication(@PathParam("userId") Long userId) {
		if (!SecurityUtils.isAdministrator()) 
			throw new UnauthorizedException();

		User user = userService.load(userId);		
		if (user.isDisabled()) {
			throw new ExplicitException("Cannot reset two factor authentication for disabled account");
		} else if (user.getType() != ORDINARY) {
			throw new ExplicitException("Cannot reset two factor authentication for service or AI account");
		} else {
			user.setTwoFactorAuthentication(null);
			userService.update(user, null);
			auditService.audit(null, "reset two factor authentication of account \"" + user.getName() + "\" via RESTful API", null, null);
			return Response.ok().build();
		}
	}
	
	@Api(order=2100)
	@Path("/{userId}/queries-and-watches")
    @POST
    public Response setQueriesAndWatches(@PathParam("userId") Long userId, @NotNull QueriesAndWatches queriesAndWatches) {
    	User user = userService.load(userId);
    	if (!SecurityUtils.isAdministrator() && !user.equals(getAuthUser())) 
			throw new UnauthorizedException();

View on GitHub (pinned to d44925c47c)

Solutions

  1. Re-enable the account first, then reset two-factor authentication
  2. Skip disabled accounts in bulk 2FA reset scripts
  3. Confirm the user's enabled state via GET /users/{userId} before resetting 2FA

Example fix

// before
await rest.post(`/users/${id}/reset-two-factor-authentication`); // fails if disabled
// after
const user = await rest.get(`/users/${id}`);
if (!user.disabled) {
  await rest.post(`/users/${id}/reset-two-factor-authentication`);
}
Defensive patterns

Strategy: validation

Validate before calling

const user = await rest.get(`/users/${userId}`); if (user.disabled) throw new Error('Cannot reset 2FA for a disabled account');

Type guard

function canReset2fa(user) { return !user.disabled && user.type === 'ORDINARY'; }

Try / catch

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; }

Prevention

When it happens

Trigger: Calling POST /rest/v1/users/{userId}/reset-two-factor-authentication as administrator for a user whose account is disabled.

Common situations: 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.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/3593228c002c2313. Report an issue: GitHub.