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

  1. Do not call createSchemaIfNotExists for Druid — schemas are fixed namespaces (druid, INFORMATION_SCHEMA, sys).
  2. Configure pre-aggregations to use an external store (e.g. Postgres) or in-Druid rollup pre-aggregations instead of external rollup tables.
  3. 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

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


AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02). Data as JSON: /api/errors/d0e746f21e70f6ec. Report an issue: GitHub.