apache/druid · error · ForbiddenException

authResult.getErrorMessage()

Error message

authResult.getErrorMessage()

What it means

SupervisorResource's specPost endpoint performs an authorization check (via AuthorizerMapper/AuthConfig) before validating and creating a supervisor spec. If the authResult does not allow access with no restriction, it throws ForbiddenException using the authorization result's error message. This is Druid's standard per-resource action check: the authenticated user lacks a required action (e.g. WRITE on DATASOURCE) for the supplied supervisor spec.

Source

Thrown at indexing-service/src/main/java/org/apache/druid/indexing/overlord/supervisor/SupervisorResource.java:157

          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());
          }
          try {
            spec.validateSpec();
          }
          catch (DruidException e) {
            return Response.status(Response.Status.BAD_REQUEST)
                           .entity(ImmutableMap.of("error", e.getMessage()))
                           .build();
          }

          final SupervisorSpecUpdateResult updateResult =
              manager.createOrUpdateAndStartSupervisor(spec, Boolean.TRUE.equals(skipRestartIfUnmodified));

          if (updateResult.isModified() || updateResult.isRestarted()) {
            auditSupervisorUpdate(spec, req);
          }

          return Response.ok(

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Grant the user's role a WRITE permission (type DATASOURCE, name = the spec's datasource, or wildcard '.*') in the authorizer JSON in coordinator dynamic config or authorizer config.
  2. Verify which authenticator/authorizer identity is being used (check the request's authentication result / auth logs) and fix credentials if the wrong identity is resolved.
  3. Check that the datasource name in the supervisor spec matches the resource patterns in the role; adjust the role or the spec.
  4. If access should be unrestricted, adjust druid.auth.authorizers / AuthConfig to use an authorizer that allows the request.

Example fix

// before: role has only READ permission
{"name": "myRole", "permissions": [{"resource": {"type": "DATASOURCE", "name": "wiki"}, "action": "READ"}]}
// after: add WRITE so supervisor POST is authorized
{"name": "myRole", "permissions": [{"resource": {"type": "DATASOURCE", "name": "wiki"}, "action": "READ"}, {"resource": {"type": "DATASOURCE", "name": "wiki"}, "action": "WRITE"}]}
Defensive patterns

Strategy: try-catch

Validate before calling

// check user permissions before POSTing the supervisor spec
fetch('/druid/indexer/v1/authorizer/test', {method:'POST', body: JSON.stringify({resource:{type:'DATASOURCE',name:spec.spec.dataSchema.dataSource}, action:'WRITE'})});

Try / catch

try { postSupervisor(spec); } catch (WebApplicationException e) { if (e.getResponse().getStatus() == 403) { handleForbidden(e.getResponse().readEntity(String.class)); } else { throw e; } }

Prevention

When it happens

Trigger: POST /druid/indexer/v1/supervisor (specPost) where the authenticated user/role fails the authorization check against the configured authorizer: required action (typically WRITE) on the target datasource resource is denied, or the resource identified in the spec is filtered out by the user's authorizer prefix.

Common situations: Operators calling the supervisor API with a service account whose role lacks write permission on the datasource; using an identity that only has READ; misconfigured druid.auth authenticator/authorizer roles missing the datasource in permissions; Kerberos/LDAP users without the expected group mappings.

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/6ece419744f2e218. Report an issue: GitHub.