risingwavelabs/risingwave · error · anyhow::Error
`catalog.type` must be set
Error message
`catalog.type` must be set
What it means
RisingWave's Iceberg connector validates an external catalog configuration in `validate_connection`. When the config does not use `hosted_catalog`, the `catalog.type` field must be set so the connector knows which catalog backend (e.g. glue, rest, jdbc) to use. The library bails out with this error because a catalog connection cannot be created or tested without it.
Source
Thrown at src/connector/src/connector_common/connection.rs:292
bail!("`catalog.type` must not be set when `hosted_catalog` is set");
}
if common.catalog_uri.is_some() {
bail!("`catalog.uri` must not be set when `hosted_catalog` is set");
}
if common.catalog_name.is_some() {
bail!("`catalog.name` must not be set when `hosted_catalog` is set");
}
if self.jdbc_user.is_some() {
bail!("`catalog.jdbc.user` must not be set when `hosted_catalog` is set");
}
if self.jdbc_password.is_some() {
bail!("`catalog.jdbc.password` must not be set when `hosted_catalog` is set");
}
return Ok(());
}
if common.catalog_type.is_none() {
bail!("`catalog.type` must be set");
}
// Test catalog
let iceberg_common = common.clone();
let mut java_map = HashMap::new();
if let Some(jdbc_user) = &self.jdbc_user {
java_map.insert("jdbc.user".to_owned(), jdbc_user.to_owned());
}
if let Some(jdbc_password) = &self.jdbc_password {
java_map.insert("jdbc.password".to_owned(), jdbc_password.to_owned());
}
let catalog = iceberg_common
.resolve_catalog_config(java_map)?
.create_catalog()
.await?;
// test catalog by `table_exists` api
let test_table_ident = IcebergTableIdentifier {View on GitHub (pinned to 6469eb736d)
Solutions
- Add `catalog.type = '<backend>'` to the connection properties (e.g. 'rest', 'glue', 'jdbc').
- If you intended RisingWave to host the catalog, set `hosted_catalog` instead.
- Double-check property spelling: the key must be exactly `catalog.type` in the WITH clause.
Example fix
// before CREATE CONNECTION iceberg_conn WITH (type = 'iceberg', catalog.uri = 'https://glue...'); // after CREATE CONNECTION iceberg_conn WITH (type = 'iceberg', catalog.type = 'glue', catalog.uri = 'https://glue...');
Defensive patterns
Strategy: validation
Validate before calling
// Validate Iceberg connection props before issuing CREATE CONNECTION
fn validate_iceberg_props(props: &serde_json::Value) -> Result<(), String> {
let obj = props.as_object().ok_or("props must be an object")?;
if !obj.contains_key("hosted_catalog") && obj.get("catalog.type").and_then(|v| v.as_str()).map_or(true, str::is_empty) {
return Err("`catalog.type` must be set when hosted_catalog is not used".into());
}
Ok(())
} Type guard
fn has_catalog_type(props: &serde_json::Value) -> bool {
props.get("catalog.type").and_then(|v| v.as_str()).map_or(false, |s| !s.is_empty())
} Prevention
- Always include `catalog.type` in Iceberg WITH clauses unless using hosted_catalog.
- Keep a checked-in SQL template for Iceberg connections and fill in placeholders.
- Validate connection props in CI before deploying DDL.
When it happens
Trigger: Calling CREATE CONNECTION / CREATE SINK / CREATE TABLE with an Iceberg catalog config that omits `catalog.type` while also not setting `hosted_catalog`.
Common situations: Users writing Iceberg connection SQL from scratch and forgetting the `catalog.type` key; copying examples that only show hosted catalog setups; typos like `catalog_type` instead of `catalog.type`.
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
- `warehouse.path` must be set in {} catalog
- create iceberg catalog for pk-index sink
- Failed to list iceberg namespaces.
- Failed to load iceberg table.
- Failed to drop iceberg table.
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/515ff576740e53b2.
Report an issue: GitHub.