theonedev/onedev · error · ExplicitException
The user is currently authenticated via external system, ple
Error message
The user is currently authenticated via external system, please change password there instead
What it means
A non-administrator can only change their own password via this endpoint, and only if the account actually has a local password. If user.getPassword() is null, the account is authenticated through an external system (LDAP, SSO, OAuth, etc.), so OneDev rejects local password changes and tells the user to change the password in the external system.
Source
Thrown at server-core/src/main/java/io/onedev/server/rest/resource/UserResource.java:500
@Api(order=2000)
@Path("/{userId}/password")
@POST
public Response setPassword(@PathParam("userId") Long userId, @Password(checkPolicy=true) @NotEmpty String password) {
User user = userService.load(userId);
if (user.isDisabled()) {
throw new ExplicitException("Cannot set password for disabled account");
} else if (user.getType() != ORDINARY) {
throw new ExplicitException("Cannot set password for service or AI account");
} if (SecurityUtils.isAdministrator()) {
user.setPassword(passwordService.encryptPassword(password));
userService.update(user, null);
if (!getAuthUser().equals(user))
auditService.audit(null, "changed password of account \"" + user.getName() + "\" via RESTful API", null, null);
return Response.ok().build();
} else if (user.equals(getAuthUser())) {
if (user.getPassword() == null) {
throw new ExplicitException("The user is currently authenticated via external system, "
+ "please change password there instead");
} else {
user.setPassword(passwordService.encryptPassword(password));
userService.update(user, null);
return Response.ok().build();
}
} else {
throw new UnauthorizedException();
}
}
@Api(order=2000)
@Path("/{userId}/ai-setting")
@POST
public Response setAiSetting(@PathParam("userId") Long userId, @NotNull AiSetting aiSetting) {
User user = userService.load(userId);
if (user.isDisabled()) {
throw new ExplicitException("Cannot set password for disabled account");View on GitHub (pinned to d44925c47c)
Solutions
- Change the password in the external identity provider (LDAP/SSO) instead
- Ask an administrator to set the password via the admin path (which bypasses this check)
- If local login is desired, migrate the account to local authentication so a password field exists
Defensive patterns
Strategy: validation
Validate before calling
const user = await rest.get(`/users/${userId}`); if (user.external || user.password == null) throw new Error('Account is externally authenticated; change password at the identity provider'); Type guard
function hasLocalPassword(user) { return user.password != null; } Try / catch
try { await rest.post(`/users/${id}/password`, {password}); } catch (e) { if (e.status === 400 && /external system/.test(e.message)) { /* redirect user to SSO/LDAP password change */ } else throw e; } Prevention
- Detect external authentication before offering local password change
- Point users at the corporate SSO/LDAP password portal
- Have admins set local passwords via the admin path when migration is intended
When it happens
Trigger: A user changing their own password (not admin path) on an account backed by external authentication (no local password stored).
Common situations: Company uses LDAP/SSO login; an employee tries to change password via OneDev REST or profile page; migrating from external auth without setting an initial local password.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Cannot set primary email address for externally authenticate
- Name is already used by another SSO provider
- Cannot set password for disabled account
- Cannot set password for service or AI account
- Unable to change password as you are authenticating via exte
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/af949d599f826387.
Report an issue: GitHub.