apache/druid · error · ForbiddenException

Cannot create table definitions in schema: %s

Error message

Cannot create table definitions in schema: %s

What it means

authorizeTable() in CatalogResource enforces that schema-level WRITE actions are only allowed on writable schemas. When a caller requests an action that includes Action.WRITE (create/edit/delete table) against a non-writable schema, it responds 403 Forbidden with this message before even checking per-table resource authorization.

Source

Thrown at extensions-core/druid-catalog/src/main/java/org/apache/druid/catalog/http/CatalogResource.java:588

  }

  private static ResourceAction resourceAction(SchemaSpec schema, String tableName, Action action)
  {
    return new ResourceAction(new Resource(tableName, schema.securityResource()), action);
  }

  private void authorizeTable(
      final SchemaSpec schema,
      final String tableName,
      final Set<Action> actions,
      final HttpServletRequest request
  ) throws CatalogException
  {
    if (Strings.isNullOrEmpty(tableName)) {
      throw CatalogException.badRequest("Table name is required");
    }
    if (actions.contains(Action.WRITE) && !schema.writable()) {
      throw new ForbiddenException(
          "Cannot create table definitions in schema: " + schema.name());
    }
    authorizeResource(new Resource(tableName, schema.securityResource()), actions, request);
  }

  private void authorizeResource(Resource resource, Set<Action> actions, HttpServletRequest request)
  {
    final AuthorizationResult authResult = AuthorizationUtils.authorizeAllResourceActions(
        request,
        actions.stream().map(action -> new ResourceAction(resource, action)).toList(),
        authorizerMapper
    );
    if (!authResult.allowAccessWithNoRestriction()) {
      throw new ForbiddenException(authResult.getErrorMessage());
    }
  }

  private static Response okWithVersion(long version)

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Switch the request to a writable schema (e.g. the 'druid' schema) where table definitions can be created.
  2. Remove WRITE actions for that schema — use GET endpoints if you only intended to read.
  3. If the schema should be writable, correct the catalog/schema configuration so SchemaSpec.writable() returns true, and ensure your role has WRITE permission.

Example fix

// before
curl -X POST .../catalog/tables -d '{"schema":"sys","name":"t",...}'

// after
curl -X POST .../catalog/tables -d '{"schema":"druid","name":"t",...}'
Defensive patterns

Strategy: validation

Validate before calling

const schema = await fetch(`/druid-ext/v1/catalog/schemas/${schemaName}`).then(r => r.json());
function canCreateTables(schema) {
  return schema && schema.writable === true; // read-only schema check
}

Try / catch

const res = await fetch(url, {method: 'POST', body});
if (res.status === 403) {
  const msg = await res.text();
  throw new Error(`Schema not writable or insufficient permissions: ${msg}`);
}

Prevention

When it happens

Trigger: POST /druid-ext/v1/catalog/tables (or PUT/DELETE on a table) targeting a schema whose SchemaSpec.writable() is false, i.e. read-only schemas such as externally managed or system schemas.

Common situations: Trying to create tables in the read-only 'sys' or metadata schemas; users of scripts written for writable schemas re-pointed at a read-only schema; catalog configuration where the schema was declared non-writable by design.

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/07b1e2c890052004. Report an issue: GitHub.