SonarSource/sonarqube · error · ForbiddenException

User does not exist

Error message

User does not exist

What it means

SonarLintClientPermissionsValidator.validateUserCanReceivePushEventForProjectUuids loads the user by UUID and throws ForbiddenException 'User does not exist' when userDao.selectByUuid returns null. It protects the push-event API so events are only prepared for real, existing users.

Source

Thrown at server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/sonarlint/SonarLintClientPermissionsValidator.java:60

    this.userSessionFactory = userSessionFactory;
  }

  public List<ProjectDto> validateUserCanReceivePushEventForProjects(UserSession userSession, Set<String> projectKeys) {
    List<ProjectDto> projectDtos;
    try (DbSession dbSession = dbClient.openSession(false)) {
      projectDtos = dbClient.projectDao().selectProjectsByKeys(dbSession, projectKeys);
    }
    validateProjectPermissions(userSession, projectDtos);
    return projectDtos;
  }

  public void validateUserCanReceivePushEventForProjectUuids(String userUuid, Set<String> projectUuids) {
    UserDto userDto;
    try (DbSession dbSession = dbClient.openSession(false)) {
      userDto = dbClient.userDao().selectByUuid(dbSession, userUuid);
    }
    if (userDto == null) {
      throw new ForbiddenException("User does not exist");
    }
    UserSession userSession = userSessionFactory.create(userDto, false);
    List<ProjectDto> projectDtos;
    try (DbSession dbSession = dbClient.openSession(false)) {
      projectDtos = dbClient.projectDao().selectByUuids(dbSession, projectUuids);
    }
    validateProjectPermissions(userSession, projectDtos);
  }

  private static void validateProjectPermissions(UserSession userSession, List<ProjectDto> projectDtos) {
    validateUsersDeactivationStatus(userSession);
    for (ProjectDto projectDto : projectDtos) {
      userSession.checkEntityPermission(ProjectPermission.USER, projectDto);
    }
  }

  private static void validateUsersDeactivationStatus(UserSession userSession) {
    if (!userSession.isActive()) {

View on GitHub (pinned to 184c821202)

Solutions

  1. Verify the userUuid against GET api/users/current and use the returned UUID.
  2. Re-create or restore the user account if it was deleted.
  3. Clear the client's cached identity/credentials and reconnect so a fresh UUID is obtained.

Example fix

// before
validator.validateUserCanReceivePushEventForProjectUuids(staleUuid, projectUuids);
// after
UserDto user = dbClient.userDao().selectByUuid(dbSession, staleUuid);
if (user != null) {
  validator.validateUserCanReceivePushEventForProjectUuids(staleUuid, projectUuids);
}
Defensive patterns

Strategy: try-catch

Validate before calling

boolean exists = dbClient.userDao().selectByUuid(dbSession, userUuid) != null; // or GET api/users/current first

Try / catch

try { validator.validateUserCanReceivePushEventForProjectUuids(uuid, uuids); } catch (ForbiddenException e) { if ("User does not exist".equals(e.getMessage())) { reconnectWithFreshIdentity(); } }

Prevention

When it happens

Trigger: Requesting push events for a userUuid that is not in the users table (deleted user, wrong UUID, stale cached UUID from a deactivated-then-purged account).

Common situations: SonarLint IDE clients holding an old user UUID after the account was deleted and recreated; environment sync where a user exists in a shadow store but not in the SonarQube DB; UUID/SCRN login confusion.

Understand the failure class

Background: "User not found", "Invalid user", and "does not exist": what missing-user lookup errors mean across Rocket.Chat, LiteLLM, Phabricator, rustfs, and pnpm — this error's family across 10 libraries.

Related errors


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