apache/druid · error · ForbiddenException

authResult.getErrorMessage()

Error message

authResult.getErrorMessage()

What it means

The POST task endpoint (taskPost) authorizes all resource actions implied by the submitted task. If the authenticated user is not granted access (result does not allow access with no restriction), it throws ForbiddenException with the authorization failure message.

Source

Thrown at indexing-service/src/main/java/org/apache/druid/indexing/overlord/http/OverlordResource.java:185

  )
  {
    final Set<ResourceAction> resourceActions;
    try {
      resourceActions = getNeededResourceActionsForTask(task);
    }
    catch (UOE e) {
      return Response.status(Response.Status.BAD_REQUEST)
                     .entity(ImmutableMap.of("error", e.getMessage()))
                     .build();
    }

    AuthorizationResult authResult = AuthorizationUtils.authorizeAllResourceActions(
        req,
        resourceActions,
        authorizerMapper
    );
    if (!authResult.allowAccessWithNoRestriction()) {
      throw new ForbiddenException(authResult.getErrorMessage());
    }

    return asLeaderWith(
        taskMaster.getTaskQueue(),
        taskQueue -> {
          try {
            taskQueue.add(task);

            if (AUDITED_TASK_TYPES.contains(task.getType())) {
              auditManager.doAudit(
                  AuditEntry.builder()
                            .key(task.getDataSource())
                            .type("task")
                            .request(AuthorizationUtils.buildRequestInfo("overlord", req))
                            .payload(new TaskIdentifier(task.getId(), task.getGroupId(), task.getType()))
                            .auditInfo(AuthorizationUtils.buildAuditInfo(req))
                            .build()
              );

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Grant the submitting user WRITE (and required READ) permissions on the datasource in their Authorizer role.
  2. Use credentials of a service account with the required datasource permissions.
  3. Use the authResult message to identify the denied resource/action and add exactly that permission.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  postTask(taskJson);
} catch (ForbiddenException | WebApplicationException e) {
  if (((WebApplicationException) e).getResponse().getStatus() == 403) {
    // request WRITE on the datasource for the submitting identity
  }
}

Prevention

When it happens

Trigger: POSTing a task to /druid/indexer/v1/task with credentials lacking required READ/WRITE access to the task's datasource — e.g. a role with only READ on the datasource, or a task touching a datasource outside the user's allowed set.

Common situations: Service accounts provisioned without ingestion permissions; tasks writing to new datasources the user cannot WRITE; misconfigured authorizer roles after a security rollout.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/16665900a3813fce. Report an issue: GitHub.