risingwavelabs/risingwave · error · anyhow::Error

`warehouse.path` must be set in storage catalog

Error message

`warehouse.path` must be set in storage catalog

What it means

When `catalog.type = 'storage'`, the warehouse location is mandatory because the storage catalog writes table metadata directly under the warehouse path. `build_storage_catalog_config` bails if `warehouse.path` is absent.

Source

Thrown at src/connector/src/connector_common/iceberg/mod.rs:617

                );
            }
            return false;
        }
        self.enable_config_load.unwrap_or(false)
    }

    fn effective_s3_path_style_access(&self) -> bool {
        // RisingWave historically inherited OpenDAL's path-style default. Iceberg now
        // defaults to virtual-host style, so preserve existing connector behavior unless
        // the user explicitly opts into virtual-host style with `false`.
        self.s3_path_style_access.unwrap_or(true)
    }

    fn build_storage_catalog_config(&self) -> ConnectorResult<CatalogBuildPlan> {
        let warehouse = self
            .warehouse_path
            .clone()
            .ok_or_else(|| anyhow!("`warehouse.path` must be set in storage catalog"))?;
        let url = Url::parse(warehouse.as_ref())
            .map_err(|_| anyhow!("Invalid warehouse path: {}", warehouse))?;

        let config = match url.scheme() {
            "s3" | "s3a" => StorageCatalogConfig::S3(
                storage_catalog::StorageCatalogS3Config::builder()
                    .warehouse(warehouse)
                    .access_key(self.s3_access_key.clone())
                    .secret_key(self.s3_secret_key.clone())
                    .region(self.s3_region.clone())
                    .endpoint(self.s3_endpoint.clone())
                    .path_style_access(Some(self.effective_s3_path_style_access()))
                    .enable_config_load(Some(self.enable_config_load()))
                    .build(),
            ),
            "gs" | "gcs" => StorageCatalogConfig::Gcs(
                storage_catalog::StorageCatalogGcsConfig::builder()
                    .warehouse(warehouse)

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Add `warehouse.path` pointing to the object-store root, e.g. 's3://bucket/path/to/warehouse'.
  2. Ensure the value is a full URL with scheme (s3, s3a, azblob) — see also the companion 'Invalid warehouse path' error.
  3. If you meant a catalog that derives the warehouse, use rest/glue instead of storage.

Example fix

// before
with ( connector='iceberg', catalog.type='storage' )
// after
with (
  connector='iceberg',
  catalog.type='storage',
  warehouse.path='s3://my-bucket/warehouse'
)
Defensive patterns

Strategy: validation

Validate before calling

if (catalogType === 'storage' && !opts['warehouse.path']) {
  throw new Error("`warehouse.path` must be set in storage catalog");
}

Try / catch

catch (e) { if (String(e).includes('warehouse.path')) { /* prompt user for warehouse.path and retry creation */ } else { throw e; } }

Prevention

When it happens

Trigger: Creating an Iceberg table/sink with `catalog.type = 'storage'` but no `warehouse.path` in the with-options.

Common situations: Users migrating config from REST/Glue catalogs where warehouse is optional or inferred; renamed option (older docs used different keys); simply forgetting the property.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/03e02e824a1e235b. Report an issue: GitHub.