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
- Switch the request to a writable schema (e.g. the 'druid' schema) where table definitions can be created.
- Remove WRITE actions for that schema — use GET endpoints if you only intended to read.
- 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
- Check schema.writable() (via the schemas API) before issuing any table write.
- Keep catalog CRUD scripts pointed at writable schemas like 'druid'.
- Ensure the authenticated user/role has WRITE on the schema security resource, not just READ.
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
- Access-Check-Result: %s
- Access-Check-Result: %s
- Unauthorized
- Could not create user [%s] due to concurrent update contenti
- Could not delete user [%s] due to concurrent update contenti
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/07b1e2c890052004.
Report an issue: GitHub.