cube-js/cube · error · Error
Unable to create schema, Druid does not support it
Error message
Unable to create schema, Druid does not support it
What it means
Druid does not support the SQL 'CREATE SCHEMA' statement — its namespaces are managed outside SQL. The driver therefore overrides createSchemaIfNotExists() to unconditionally throw, rather than sending SQL Druid would reject.
Source
Thrown at packages/cubejs-druid-driver/src/DruidDriver.ts:136
public async query<R = unknown>(query: string, values: unknown[] = []): Promise<Array<R>> {
const result = await this.client.query<R>(query, this.normalizeQueryValues(values));
return result.rows;
}
public informationSchemaQuery() {
return `
SELECT
COLUMN_NAME as ${this.quoteIdentifier('column_name')},
TABLE_NAME as ${this.quoteIdentifier('table_name')},
TABLE_SCHEMA as ${this.quoteIdentifier('table_schema')},
DATA_TYPE as ${this.quoteIdentifier('data_type')}
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA NOT IN ('INFORMATION_SCHEMA', 'sys')
`;
}
public async createSchemaIfNotExists(schemaName: string): Promise<void> {
throw new Error('Unable to create schema, Druid does not support it');
}
public async getTablesQuery(schemaName: string) {
return this.query<TableQueryResult>('SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ?', [
schemaName
]);
}
public async downloadQueryResults(query: string, values: unknown[], _options: DownloadQueryResultsOptions): Promise<DownloadQueryResultsResult> {
const { rows, columns } = await this.client.query<any>(query, this.normalizeQueryValues(values));
if (!columns) {
throw new Error(
'You are using an old version of Druid. Unable to detect column types in readOnly mode.'
);
}
const types: TableStructure = [];
View on GitHub (pinned to 7d981676b3)
Solutions
- Do not call createSchemaIfNotExists for Druid — schemas are fixed namespaces (druid, INFORMATION_SCHEMA, sys).
- Configure pre-aggregations to use an external store (e.g. Postgres) or in-Druid rollup pre-aggregations instead of external rollup tables.
- Wrap the call with a no-op if your abstraction requires it and you know the schema is a Druid namespace.
Example fix
// before
await driver.createSchemaIfNotExists('staging');
// after
if (driver.constructor.name !== 'DruidDriver') {
await driver.createSchemaIfNotExists('staging');
} Defensive patterns
Strategy: validation
Validate before calling
function supportsCreateSchema(driver) {
return typeof driver.createSchemaIfNotExists === 'function' &&
driver.constructor.name !== 'DruidDriver';
}
if (supportsCreateSchema(driver)) await driver.createSchemaIfNotExists(schema); Try / catch
try {
await driver.createSchemaIfNotExists(schema);
} catch (e) {
if (e.message.includes('Druid does not support')) return; // expected no-op
throw e;
} Prevention
- Skip schema-creation steps for Druid datasources
- Use external rollup stores (Postgres) or in-Druid pre-aggregations instead of external staging schemas
- Feature-detect driver capabilities before generic schema setup code
When it happens
Trigger: Calling driver.createSchemaIfNotExists('my_schema') directly, or Cube's pre-aggregation/compiler flow attempting to ensure a staging schema exists for a Druid datasource.
Common situations: Enabling pre-aggregations with a driver-level staging schema for Druid; migrating generic driver code (e.g. copied from Postgres setup) that calls createSchemaIfNotExists; tooling that assumes all JDBC-ish drivers can create schemas.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- e.response.data.errorMessage
- You cannot change security context via __user from ${session
- Incorrect user name "${user}" or password
- ${queryExecution.QueryExecution?.Status?.StateChangeReason}
- Unsupported parameter type for SQL escaping: ${typeof value}
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/d0e746f21e70f6ec.
Report an issue: GitHub.