theonedev/onedev · error · ExplicitException

Cannot add ssh key for disabled user

Error message

Cannot add ssh key for disabled user

What it means

OneDev throws this ExplicitException from the addSshKey REST endpoint when attempting to add an SSH public key to a disabled user account. Disabled accounts cannot authenticate, so attaching new SSH credentials to them is disallowed. Only admins or the user themself pass the preceding authorization check.

Source

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

		if (!getAuthUser().equals(user)) {
			var newAuditContent = VersionedXmlDoc.fromBean(queriesAndWatches).toXML();
			auditService.audit(null, "changed queries and watches of account \"" + user.getName() + "\" via RESTful API", oldAuditContent, newAuditContent);
		}

		return Response.ok().build();
    }
	
	@Api(order=2200)
	@Path("/{userId}/ssh-keys")
	@POST
	public Long addSshKey(@PathParam("userId") Long userId, @NotNull String content) {
		User user = userService.load(userId);
		if (!SecurityUtils.isAdministrator() && !user.equals(getAuthUser()))
			throw new UnauthorizedException();
		
		if (user.isDisabled())
			throw new ExplicitException("Cannot add ssh key for disabled user");

		SshKey sshKey = new SshKey();
		sshKey.setContent(content);
		sshKey.setCreatedAt(new Date());
		sshKey.setOwner(user);
		sshKey.generateFingerprint();
        
		sshKeyService.create(sshKey);

		if (!getAuthUser().equals(user)) {
			var newAuditContent = VersionedXmlDoc.fromBean(sshKey).toXML();
			auditService.audit(null, "added ssh key to account \"" + user.getName() + "\" via RESTful API", null, newAuditContent);
		}

		return sshKey.getId();
	}
	
	@Api(order=2300)

View on GitHub (pinned to d44925c47c)

Solutions

  1. Enable the user account first, then add the SSH key
  2. Skip key provisioning for disabled users in automation
  3. Verify the account status via getUser() before POSTing the key

Example fix

// before
restClient.addSshKey(userId, pubKey);
// after
User u = restClient.getUser(userId);
if (!u.isDisabled()) restClient.addSshKey(userId, pubKey);
Defensive patterns

Strategy: validation

Validate before calling

User u = getUser(userId); if (u.isDisabled()) throw new SkipException("user disabled");

Type guard

boolean canManageKeys(User u) { return u != null && !u.isDisabled(); }

Try / catch

try { addSshKey(userId, key); } catch (ExplicitException e) { log.warn("ssh key not added: {}", e.getMessage()); }

Prevention

When it happens

Trigger: POSTing an SSH key to /users/{userId}/ssh-keys where the target user has isDisabled()==true.

Common situations: Provisioning scripts that create users and add SSH keys in one run, where the user was created disabled or disabled by policy; re-adding keys to an offboarded account.

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/015d3b2217d217de. Report an issue: GitHub.