risingwavelabs/risingwave · error · anyhow::Error

Invalid warehouse path: {}

Error message

Invalid warehouse path: {}

What it means

The computed table location is derived from `warehouse` plus the namespace/table name. If the warehouse path is not a parseable URL and the catalog is not a REST catalog (where a logical warehouse name is allowed), creating a location is impossible and the code bails with 'Invalid warehouse path: {}'.

Source

Thrown at src/connector/src/sink/iceberg/create_table.rs:168

        let mut names = namespace.clone().inner();
        names.push(table_name.clone());
        match &config.common.warehouse_path {
            Some(warehouse_path) => {
                let is_s3_tables = warehouse_path.starts_with("arn:aws:s3tables");
                // Lakehouse Iceberg REST catalog federation uses bq:// prefix for BigQuery-managed Iceberg tables.
                let is_bq_catalog_federation = warehouse_path.starts_with("bq://");
                let url = Url::parse(warehouse_path);
                if url.is_err() || is_s3_tables || is_bq_catalog_federation {
                    // For rest catalog, the warehouse_path could be a warehouse name.
                    // In this case, we should specify the location when creating a table.
                    if config
                        .common
                        .is_rest_catalog()
                        .map_err(|err| SinkError::Config(anyhow!(err)))?
                    {
                        None
                    } else {
                        bail!(format!("Invalid warehouse path: {}", warehouse_path))
                    }
                } else if warehouse_path.ends_with('/') {
                    Some(format!("{}{}", warehouse_path, names.join("/")))
                } else {
                    Some(format!("{}/{}", warehouse_path, names.join("/")))
                }
            }
            None => None,
        }
    };

    let partition_spec = match &config.partition_by {
        Some(partition_by) => {
            let mut partition_fields = Vec::<UnboundPartitionField>::new();
            for (i, (column, transform)) in parse_partition_by_exprs(partition_by.clone())?
                .into_iter()
                .enumerate()
            {

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Change `warehouse` to an absolute object-store URL like `s3://bucket/iceberg/`.
  2. Alternatively switch to a REST catalog, which permits warehouse names without a URL.
  3. Validate the warehouse URI format before creating the sink.
  4. Check for typos or empty values in the warehouse option.

Example fix

// before
WITH (connector='iceberg', catalog.type='jdbc', warehouse='prod_warehouse')
// after
WITH (connector='iceberg', catalog.type='jdbc', warehouse='s3://my-bucket/prod_warehouse/')
Defensive patterns

Strategy: validation

Validate before calling

// Validate warehouse URI format before invoking sink creation
match url::Url::parse(warehouse) {
    Ok(_) => {},
    Err(_) if is_rest_catalog => {}, // logical names allowed
    Err(_) => eprintln!("Invalid warehouse path: {warehouse} — use e.g. s3://bucket/path/"),
}

Type guard

fn is_valid_warehouse(warehouse: &str, is_rest: bool) -> bool {
    is_rest || url::Url::parse(warehouse).is_ok()
}

Try / catch

match result {
    Err(e) if e.to_string().starts_with("Invalid warehouse path") => {
        // correct the warehouse option to an absolute URL or switch to a REST catalog
    }
    other => other?,
}

Prevention

When it happens

Trigger: In create_table_if_not_exists_impl, url parsing of warehouse_path fails (or is_s3_tables/is_bq_catalog_federation apply) and is_rest_catalog() returns false, so the code cannot derive None for the location and calls bail! with the raw warehouse_path value.

Common situations: Using a Hive/JDBC/Glue catalog with `warehouse` set to a logical name instead of an object-store URI; missing s3://, gs://, or file:// prefix; trailing placeholder text in warehouse option.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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