theonedev/onedev · error · ExplicitException
Cannot delete primary email address of externally authentica
Error message
Cannot delete primary email address of externally authenticated user
What it means
deleteEmailAddress refuses to remove a user's primary email address when the account has no local password, i.e. it is authenticated externally (SSO/LDAP). The primary address is the account identity for such users, so deleting it would leave the externally-authenticated account without a resolvable email. It throws ExplicitException, which is surfaced as a user-facing message.
Source
Thrown at server-core/src/main/java/io/onedev/server/rest/resource/EmailAddressResource.java:142
throw new ExplicitException("Unable to send verification email as mail service is not configured");
if (emailAddress.isVerified())
throw new ExplicitException("Unable to send verification email as this email address is already verified");
emailAddressService.sendVerificationEmail(emailAddress);
return emailAddressId;
}
@Api(order=300)
@Path("/{emailAddressId}")
@DELETE
public Response deleteEmailAddress(@PathParam("emailAddressId") Long emailAddressId) {
var emailAddress = emailAddressService.load(emailAddressId);
if (!SecurityUtils.isAdministrator() && !emailAddress.getOwner().equals(getAuthUser()))
throw new UnauthorizedException();
if (emailAddress.isPrimary() && emailAddress.getOwner().getPassword() == null) {
throw new ExplicitException("Cannot delete primary email address of "
+ "externally authenticated user");
}
if (emailAddress.getOwner().getEmailAddresses().size() == 1)
throw new ExplicitException("At least one email address should be present for a user");
emailAddressService.delete(emailAddress);
if (!getAuthUser().equals(emailAddress.getOwner()))
auditService.audit(null, "deleted email address \"" + emailAddress.getValue() + "\" from account \"" + emailAddress.getOwner().getName() + "\" via RESTful API", null, null);
return Response.ok().build();
}
}
View on GitHub (pinned to d44925c47c)
Solutions
- Delete a non-primary address instead, or add another address first.
- For an externally authenticated user, update the email at the identity provider (LDAP/OAuth source) rather than in OneDev.
- Convert the user to password (local) authentication if you truly need to change their primary address locally.
- As admin, manage the account via the UI which offers clearer guidance for external accounts.
Defensive patterns
Strategy: validation
Validate before calling
// skip primary address of externally authenticated users
if (address.isPrimary() && address.getOwner().getPassword() == null) {
log.info("Skipping primary address of external user " + address.getOwner().getName());
return;
} Try / catch
try { client.deleteEmailAddress(id); }
catch (ExplicitException e) { /* expected for primary/external/last address — treat as skip */ } Prevention
- Check isPrimary() and owner password state before deleting.
- Manage SSO/LDAP user emails at the identity provider, not via OneDev API.
- Filter external-authenticated accounts out of bulk address-pruning jobs.
When it happens
Trigger: DELETE /~api/emailAddresses/{id} where emailAddress.isPrimary() is true and emailAddress.getOwner().getPassword() == null (user authenticates via LDAP/SSO instead of a OneDev password).
Common situations: Users synchronized from LDAP or logging in via OAuth/SSO whose only stable email is the primary one; automation scripts bulk-pruning addresses that hit the primary of an SSO 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.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- This email address is already used by another user
- Cannot set primary email address for externally authenticate
- At least one email address should be present for a user
- Not authorized
- Name is already used by another SSO provider
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/1af2ed08dd00a973.
Report an issue: GitHub.