{"record":{"id":"36a4d4ec9b8619e1","repo":"SonarSource/sonarqube","slug":"insufficient-privileges-36a4d4","errorCode":null,"errorMessage":"Insufficient privileges","messagePattern":"Insufficient privileges","errorType":"http","errorClass":"ForbiddenException","httpStatus":403,"severity":"warning","filePath":"server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/system/controller/HealthController.java","lineNumber":68,"sourceCode":"  private final SystemPasscode systemPasscode;\n  private final NodeInformation nodeInformation;\n  private final UserSession userSession;\n\n  @Autowired(required=true)\n  public HealthController(HealthChecker healthChecker, SystemPasscode systemPasscode, @Nullable NodeInformation nodeInformation,\n    @Nullable UserSession userSession) {\n    this.healthChecker = healthChecker;\n    this.systemPasscode = systemPasscode;\n    this.nodeInformation = nodeInformation;\n    this.userSession = userSession;\n  }\n\n  @GetMapping\n  public Health getHealth(@RequestHeader(value = \"X-Sonar-Passcode\", required = false) String requestPassCode) {\n    if (systemPasscode.isValidPasscode(requestPassCode) || isSystemAdmin()) {\n      return getHealth();\n    }\n    throw new ForbiddenException(\"Insufficient privileges\");\n  }\n\n  private Health getHealth() {\n    if (nodeInformation == null || nodeInformation.isStandalone()) {\n      return healthChecker.checkNode();\n    }\n    throw new ServerException(HTTP_NOT_IMPLEMENTED, \"Unsupported in cluster mode\");\n  }\n\n  private boolean isSystemAdmin() {\n    if (userSession == null) {\n      return false;\n    }\n    return userSession.isSystemAdministrator();\n  }\n}\n","sourceCodeStart":50,"sourceCodeEnd":85,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/system/controller/HealthController.java#L50-L85","documentation":"ForbiddenException thrown by HealthController.getHealth when the request has neither a valid X-Sonar-Passcode header nor a system-admin user session. The health endpoint requires explicit privilege before returning node health details.","triggerScenarios":"GET /api/v2/system/health without X-Sonar-Passcode matching sonar.web.systemPasscode and without an Administer System session.","commonSituations":"Health-check scripts missing the passcode header, passcode rotated without updating monitoring, non-admin service accounts calling the endpoint.","solutions":["Send the configured system passcode in the X-Sonar-Passcode header","Use a session of a user holding Administer System permission","Align monitoring tooling with the current sonar.web.systemPasscode value"],"exampleFix":"// before\ncurl http://sonarqube:9000/api/v2/system/health\n// after\ncurl -H \"X-Sonar-Passcode: $SONAR_PASSCODE\" http://sonarqube:9000/api/v2/system/health","handlingStrategy":"validation","validationCode":"if [ -z \"$SONAR_PASSCODE\" ]; then echo \"provide X-Sonar-Passcode\" >&2; exit 1; fi\ncurl -sf -H \"X-Sonar-Passcode: $SONAR_PASSCODE\" http://sonarqube:9000/api/v2/system/health","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Configure monitoring with the current system passcode","Use admin sessions only when passcode auth is impractical","Keep passcode in a managed secret, not hardcoded"],"tags":["java","authorization","health-check"],"backgroundTag":"insufficient-permissions","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}