SonarSource/sonarqube · error · ForbiddenException

Insufficient privileges

Error message

Insufficient privileges

What it means

SafeModeLivenessAction serves api/safe_mode/liveness, used to report process liveness during safe mode. Like the other safe-mode endpoints it authenticates via the system passcode, not user sessions; a request without a valid sonar.web.systemPasscode value gets ForbiddenException 'Insufficient privileges'.

Source

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

public class SafeModeLivenessAction implements SystemWsAction {
  private final LivenessActionSupport livenessActionSupport;
  private final SystemPasscode systemPasscode;

  public SafeModeLivenessAction(LivenessActionSupport livenessActionSupport, SystemPasscode systemPasscode) {
    this.livenessActionSupport = livenessActionSupport;
    this.systemPasscode = systemPasscode;
  }

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

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

    livenessActionSupport.checkliveness(response);
  }
}

View on GitHub (pinned to 184c821202)

Solutions

  1. Configure sonar.web.systemPasscode on the server and include the matching X-Sonar-Passcode header in the liveness probe request.
  2. Synchronize the secret used by the probe with the server property (same Kubernetes secret/env value) and redeploy the probe after rotation.
  3. Verify the passcode is not empty and the probe hits the correct port/context path.

Example fix

// before
livenessProbe: { httpGet: { path: '/api/safe_mode/liveness', port: 9000 } }
// after
livenessProbe: { httpGet: { path: '/api/safe_mode/liveness', port: 9000 }, httpHeaders: [{ name: 'X-Sonar-Passcode', valueFrom: 'systemPasscode' }] }
Defensive patterns

Strategy: validation

Validate before calling

const passcode = k8sSecret['sonar-system-passcode'];
if (!passcode) throw new Error('liveness probe cannot start without system passcode');

Try / catch

try {
  await probe('/api/safe_mode/liveness', { 'X-Sonar-Passcode': passcode });
} catch (e) {
  if (e.status === 403) failProbe('invalid system passcode');
  else throw e;
}

Prevention

When it happens

Trigger: Calling api/safe_mode/liveness without the X-Sonar-Passcode header / passcode parameter, or with an incorrect value while the node is starting up in safe mode.

Common situations: Orchestrator liveness probes (Kubernetes livenessProbe) configured before sonar.web.systemPasscode was set; probe secret desynchronized after passcode rotation in a Helm chart or sonar.properties.

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/03f11ea6cab4a497. Report an issue: GitHub.