SonarSource/sonarqube · error · ForbiddenException

Insufficient privileges

Error message

Insufficient privileges

What it means

SafeModeHealthAction serves the safe-mode health Web API (api/safe_mode/health) and is protected by the system pass code rather than a user session. If the request does not carry the correct passcode (header or parameter configured as sonar.web.systemPasscode), the action throws ForbiddenException 'Insufficient privileges' without evaluating node health.

Source

Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/SafeModeHealthAction.java:46

public class SafeModeHealthAction implements SystemWsAction {
  private final HealthActionSupport support;
  private final SystemPasscode systemPasscode;

  public SafeModeHealthAction(HealthActionSupport support, SystemPasscode systemPasscode) {
    this.support = support;
    this.systemPasscode = systemPasscode;
  }

  @Override
  public void define(WebService.NewController controller) {
    support.define(controller, this);
  }

  @Override
  public void handle(Request request, Response response) throws Exception {
    if (!systemPasscode.isValid(request)) {
      throw new ForbiddenException("Insufficient privileges");
    }

    WsUtils.writeProtobuf(support.checkNodeHealth(), request, response);
  }
}

View on GitHub (pinned to 184c821202)

Solutions

  1. Set/verify sonar.web.systemPasscode in sonar.properties and send its value via the X-Sonar-Passcode header (or passcode parameter) on the health request.
  2. Re-check the client side secret: confirm the monitoring tool's stored passcode matches the current server value and restart/reload it after rotation.
  3. If passcode auth is not desired for probes, restrict the endpoint at the network level and configure the passcode for the probing system specifically.

Example fix

// before
curl http://sonarqube:9000/api/safe_mode/health
// after
curl -H "X-Sonar-Passcode: $SONAR_SYSTEM_PASSCODE" http://sonarqube:9000/api/safe_mode/health
Defensive patterns

Strategy: validation

Validate before calling

if (!process.env.SONAR_SYSTEM_PASSCODE) {
  throw new Error('SONAR_SYSTEM_PASSCODE must be set to call safe-mode WS');
}

Try / catch

try {
  await http.get('/api/safe_mode/health', { headers: { 'X-Sonar-Passcode': passcode } });
} catch (e) {
  if (e.status === 403) {
    log('passcode invalid or missing; reload from secret');
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling api/safe_mode/health without the sonar.web.systemPasscode value, or with a wrong/expired passcode, e.g. during a SonarQube startup where the health check runs before the passcode was configured.

Common situations: Load balancers or Kubernetes probes scraping the safe-mode health endpoint with credentials not set (property missing in sonar.properties) or rotated in one place but not the other; monitoring agents after a passcode change.

Understand the failure class

Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.

Related errors


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