SonarSource/sonarqube · error
User with login '{}' tried to login with email '{}' which do
Error message
User with login '{}' tried to login with email '{}' which doesn't match the email on record '{}' What it means
UserRegistrarImpl.validateEmailToAvoidLoginRecycling throws an authentication failure when an identity provider login (e.g. GitHub/ALM SSO) matches an existing SonarQube user whose stored email differs from the email presented by the provider. It exists to prevent login recycling: someone re-registering a provider login must not silently take over an account tied to a different email. The warning log (with provider login, presented email, and recorded email) precedes a failAuthenticationException, aborting authentication for that user.
Source
Thrown at server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/UserRegistrarImpl.java:153
if (BITBUCKET_PROVIDER.equals(key)) {
validateExternalIdToAvoidLoginRecycling(userIdentity, user, source);
}
return true;
}
private static void validateEmailToAvoidLoginRecycling(UserIdentity userIdentity, UserDto user, Source source) {
String dbEmail = user.getEmail();
if (dbEmail == null) {
return;
}
String externalEmail = userIdentity.getEmail();
if (!dbEmail.equalsIgnoreCase(externalEmail)) {
LOGGER.warn("User with login '{}' tried to login with email '{}' which doesn't match the email on record '{}'", userIdentity.getProviderLogin(), externalEmail, dbEmail);
throw failAuthenticationException(userIdentity, source);
}
}
private static void validateExternalIdToAvoidLoginRecycling(UserIdentity userIdentity, UserDto user, Source source) {
if (!userExternalIdMatchesLogin(user)) {
LOGGER.warn("User '{}' matched by external login, but the stored external ID differs - possible recycled external username", userIdentity.getProviderLogin());
throw failAuthenticationException(userIdentity, source);
}
}
private static boolean userExternalIdMatchesLogin(UserDto user) {
return Objects.equals(user.getExternalId(), user.getExternalLogin());
}
private static AuthenticationException failAuthenticationException(UserIdentity userIdentity, Source source) {
String message = String.format("Failed to authenticate with login '%s'", userIdentity.getProviderLogin());
return authException(userIdentity, source, message, message);View on GitHub (pinned to 184c821202)
Solutions
- Update the user's email in SonarQube (Users administration page or update web service) to match the email now returned by the identity provider.
- Have the user correct their email at the identity provider (GitHub/GitLab/Azure DevOps profile) back to the recorded value if the provider change was unintended.
- If the provider login was genuinely recycled by a different person, deactivate or delete the stale SonarQube account and let the new user register fresh.
- Check identity-provisioning (SCIM/SAML/JIT) settings so email updates propagate to SonarQube instead of diverging.
Example fix
// before (admin panel: email mismatch blocks login) user email: alice@old-company.com, IdP email: alice@new-company.com // after UPDATE via Administration > Users > alice > Edit: set email to alice@new-company.com (matching the IdP), or update upstream and re-provision.
Defensive patterns
Strategy: validation
Validate before calling
// Admin/automation check before enabling ALM login for a user
boolean emailMatches = userStoredEmail.equalsIgnoreCase(identityProviderEmail);
if (!emailMatches) { updateUserEmail(userId, identityProviderEmail); } Prevention
- Keep SonarQube user emails synchronized with the identity provider (enable SCIM or periodic sync).
- When users change their IdP email, update the SonarQube account in the same change window.
- Avoid hand-editing user emails in SonarQube when ALM/SSO provisioning is active.
When it happens
Trigger: A user authenticates via an ALM/identity provider whose providerLogin matches an existing SonarQube user account, but the email claim in the UserIdentity does not case-insensitively equal the email stored in the DB (user.getEmail()); validateAlmSpecificData calls validateEmailToAvoidLoginRecycling during user provisioning.
Common situations: User changed their email at the identity provider but the SonarQube account still holds the old address; two different provider accounts share a login after a provider re-provisioned accounts; admin manually edited the SonarQube email out of sync with the IdP; SCIM/provisioning updated email upstream but not in SonarQube.
Related errors
- User '{}' matched by external login, but the stored external
- Failed to fetch GitLab repository URL for ALM setting '{}' a
- Failed to fetch Azure repository URL for ALM setting '{}', p
- Skipping GitHub authentication setup: {}
- Invalid personal access token
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/0aa6d3d1f80755da.
Report an issue: GitHub.