{"record":{"id":"af75a3e716fb7f9c","repo":"SonarSource/sonarqube","slug":"email-s-is-already-used","errorCode":null,"errorMessage":"Email '%s' is already used","messagePattern":"Email '(.+?)' is already used","errorType":"exception","errorClass":"AuthenticationException","httpStatus":401,"severity":"error","filePath":"server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/UserRegistrarImpl.java","lineNumber":230,"sourceCode":"    userUpdater.updateAndCommit(dbSession, userDto, update, beforeCommit(dbSession, authenticatorParameters), toArray(otherUserToIndex));\n    return userDto;\n  }\n\n  private Consumer<UserDto> beforeCommit(DbSession dbSession, UserRegistration authenticatorParameters) {\n    return user -> syncGroups(dbSession, authenticatorParameters.getUserIdentity(), user);\n  }\n\n  private Optional<UserDto> detectEmailUpdate(DbSession dbSession, UserRegistration authenticatorParameters, @Nullable String authenticatingUserUuid) {\n    String email = authenticatorParameters.getUserIdentity().getEmail();\n    if (email == null) {\n      return Optional.empty();\n    }\n    List<UserDto> existingUsers = dbClient.userDao().selectByEmail(dbSession, email);\n    if (existingUsers.isEmpty()) {\n      return Optional.empty();\n    }\n    if (existingUsers.size() > 1) {\n      throw generateExistingEmailError(authenticatorParameters, email);\n    }\n\n    UserDto existingUser = existingUsers.get(0);\n    if (existingUser == null || existingUser.getUuid().equals(authenticatingUserUuid)) {\n      return Optional.empty();\n    }\n    throw generateExistingEmailError(authenticatorParameters, email);\n  }\n\n  private void syncGroups(DbSession dbSession, UserIdentity userIdentity, UserDto userDto) {\n    if (!userIdentity.shouldSyncGroups()) {\n      return;\n    }\n    String userLogin = userDto.getLogin();\n    Set<String> userGroups = new HashSet<>(dbClient.groupMembershipDao().selectGroupsByLogins(dbSession, singletonList(userLogin)).get(userLogin));\n    Set<String> identityGroups = userIdentity.getGroups();\n    LOGGER.debug(\"List of groups returned by the identity provider '{}'\", identityGroups);\n","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/UserRegistrarImpl.java#L212-L248","documentation":"UserRegistrarImpl.detectEmailUpdate resolves conflicts when an authenticating user's email already exists in the database. If more than one user already holds that email, it immediately throws 'Email <email> is already used' because the target user cannot be determined unambiguously.","triggerScenarios":"Login/registration where selectByEmail returns more than one UserDto for the email being assigned — duplicated email rows in the users table.","commonSituations":"Historical duplicates created before email-uniqueness enforcement; data imported/migrated from another instance; manual DB edits; case-variant duplicates from old SonarQube versions.","solutions":["Query the users table for that email and identify/merge or delete the duplicate accounts.","Decide which account is legitimate and update its email; deactivate or rename the other.","After cleanup, have the user log in again.","Prevent recurrence by enforcing email uniqueness and cleaning up before migrations."],"exampleFix":"// before\nSELECT uuid FROM users WHERE email='a@x.com'; -- returns 2 rows\n// after: deactivate the stale duplicate\nUPDATE users SET active=false, email='old+a@x.com' WHERE uuid='stale-uuid';","handlingStrategy":"validation","validationCode":"-- SQL: detect duplicate emails before login/registration fails\nSELECT email, count(*) AS n FROM users WHERE active = true GROUP BY email HAVING count(*) > 1;","typeGuard":null,"tryCatchPattern":"try {\n  return detectEmailUpdate(dbSession, authenticatorParameters, email);\n} catch (MessageException e) {\n  LOG.error(\"Ambiguous email: multiple users already hold it; dedupe required\", e);\n  throw e;\n}","preventionTips":["Run a duplicate-email audit before SonarQube upgrades","Enforce email uniqueness when importing users","Merge or deactivate duplicate accounts promptly","Never hand-edit the users table without a backup"],"tags":["authentication","sonarqube","email-conflict","database","duplicate"],"backgroundTag":"conflicting-config-options","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}