cube-js/cube · error · Error

Unload is not configured

Error message

Unload is not configured

What it means

A configuration guard in BigQueryDriver.unload: unload() can only export a table by writing `*.csv.gz` objects to a GCS bucket, so this fires when no bucket was configured on the driver (e.g. CUBEJS_UNLOAD_BUCKET / export bucket options missing). It prevents an attempted BigQuery extract with no destination; the fix is to supply the unload bucket configuration before calling unload.

Source

Thrown at packages/cubejs-bigquery-driver/src/BigQueryDriver.ts:359

      query,
      params: values,
      parameterMode: 'positional',
      useLegacySql: false,
      wrapIntegers: true,
      ...(labels ? { labels } : {}),
    });

    const rowStream = new HydrationStream();
    stream.pipe(rowStream);

    return {
      rowStream,
    };
  }

  public async unload(table: string): Promise<TableCSVData> {
    if (!this.bucket) {
      throw new Error('Unload is not configured');
    }

    const destination = this.bucket.file(`${table}-*.csv.gz`);
    const [schema, tableName] = table.split('.');
    const bigQueryTable = this.bigquery.dataset(schema).table(tableName);
    const [job] = await bigQueryTable.createExtractJob(destination, { format: 'CSV', gzip: true });
    await this.waitForJobResult(job, { table }, false);
    // There is an implementation for extracting and signing urls from S3
    // @see BaseDriver->extractUnloadedFilesFromS3()
    // Please use that if you need. Here is a different flow
    // because bigquery requires storage/bucket object for other things,
    // and there is no need to initiate another one (created in extractUnloadedFilesFromS3()).
    const [files] = await this.bucket.getFiles({ prefix: `${table}-` });
    const urls = await Promise.all(files.map(async file => {
      const [url] = await file.getSignedUrl({
        action: 'read',
        expires: new Date(new Date().getTime() + 60 * 60 * 1000),
      });

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Configure the bucket option (or relevant GCS bucket env config) when creating BigQueryDriver
  2. Verify GCS credentials allow access to the configured bucket
  3. Confirm you are on the intended code path — unload requires bucket config by design
  4. Use query()/rows-based transfer instead of unload if bucket storage is unavailable

Example fix

// before
new BigQueryDriver({ projectId: 'p', keyFile: 'k.json' });
driver.unload('ds.tbl'); // throws
// after
new BigQueryDriver({ projectId: 'p', keyFile: 'k.json', bucket: 'gs://my-unload-bucket' });
driver.unload('ds.tbl');
Defensive patterns

Strategy: validation

Validate before calling

const driver = new BigQueryDriver(opts);
if (!opts.bucket) throw new Error('bucket option is required for BigQuery unload');

Type guard

function canUnload(d: BigQueryDriver): boolean {
  return !!(d as any).bucket;
}

Try / catch

try {
  csv = await driver.unload('ds.table');
} catch (e) {
  if (/Unload is not configured/.test(e.message)) {
    console.error('Configure the GCS bucket option for BigQuery unload flows');
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling driver.unload(table) when the driver was constructed without bucket/bucketUri unload configuration.

Common situations: Forgetting to set the bucket option for unload-based flows (e.g. Cube Store load via GCS), missing GCS permissions preventing bucket initialization, or copying config from a non-unload setup.

Related errors


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