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

  1. Update the user's email in SonarQube (Users administration page or update web service) to match the email now returned by the identity provider.
  2. 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.
  3. 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.
  4. 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

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


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/0aa6d3d1f80755da. Report an issue: GitHub.