{"record":{"id":"4f918352dc072662","repo":"SonarSource/sonarqube","slug":"insufficient-privileges-4f9183","errorCode":null,"errorMessage":"Insufficient privileges","messagePattern":"Insufficient privileges","errorType":"exception","errorClass":"ForbiddenException","httpStatus":403,"severity":"error","filePath":"server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/CancelAction.java","lineNumber":92,"sourceCode":"  public void handle(Request wsRequest, Response wsResponse) {\n    String taskId = wsRequest.mandatoryParam(PARAM_TASK_ID);\n    try (DbSession dbSession = dbClient.openSession(false)) {\n      Optional<CeQueueDto> queueDto = dbClient.ceQueueDao().selectByUuid(dbSession, taskId);\n      queueDto.ifPresent(dto -> {\n        checkPermission(dbSession, dto);\n        queue.cancel(dbSession, dto);\n      });\n    }\n    wsResponse.noContent();\n  }\n\n  private void checkPermission(DbSession dbSession, CeQueueDto ceQueueDto) {\n    if (userSession.isSystemAdministrator()) {\n      return;\n    }\n    String componentUuid = ceQueueDto.getComponentUuid();\n    if (componentUuid == null) {\n      throw insufficientPrivilegesException();\n    }\n    Optional<ComponentDto> component = dbClient.componentDao().selectByUuid(dbSession, componentUuid);\n    if (!component.isPresent()) {\n      throw insufficientPrivilegesException();\n    }\n    userSession.checkComponentPermission(ProjectPermission.ADMIN, component.get());\n  }\n}\n","sourceCodeStart":74,"sourceCodeEnd":101,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/CancelAction.java#L74-L101","documentation":"ForbiddenException 'Insufficient privileges' from /api/ce/cancel_task when the caller is not a system administrator and the queued task has no componentUuid (e.g. a Compute Engine task not tied to a project). Non-admins can only cancel tasks of projects where they hold Admin permission.","triggerScenarios":"POST /api/ce/cancel_task?id=... for a project-less CE task (purge/migration/internal tasks) as a non-admin; canceling while the task's componentUuid is null.","commonSituations":"Attempting to clear a stuck background task via API without admin rights; automation scripts written for project tasks reused on internal tasks.","solutions":["Perform the cancellation with a system-administrator account/token.","Only cancel tasks that belong to a project on which you have 'Administer Project'; check GET /api/ce/task?id=... first.","For project-less stuck tasks, restart the Compute Engine or ask an admin.","Verify the task UUID via GET /api/ce/activity before canceling."],"exampleFix":"// before\nPOST /api/ce/cancel_task?id=<internal-task-uuid>  -> 403 (no componentUuid, non-admin)\n// after: run as admin token or target a project task you administer\nPOST /api/ce/cancel_task?id=<project-task-uuid>  (with project Admin permission)","handlingStrategy":"validation","validationCode":"// before canceling, inspect the task\nTASK=$(curl -s -u \"$TOKEN:\" \"$SONAR/api/ce/task?id=$TASK_ID\")\necho \"$TASK\" | grep -q '\"componentUuid\"' || echo \"task has no component: admin required to cancel\"","typeGuard":null,"tryCatchPattern":"try {\n  ws.post(\"/api/ce/cancel_task\", form(id));\n} catch (ForbiddenException e) {\n  log.warn(\"Need admin or project Admin to cancel task {}\", id);\n  throw e;\n}","preventionTips":["Only automate cancellation of project-bound tasks with proper Admin permission.","Reserve project-less task management for admin accounts.","Check /api/ce/pending ownership before canceling."],"tags":["sonarqube","webapi","compute-engine","permissions"],"backgroundTag":"insufficient-permissions","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}