risingwavelabs/risingwave · error · SinkError::Iceberg
failed to create iceberg namespace: {namespace}
Error message
failed to create iceberg namespace: {namespace} What it means
After confirming a namespace does not exist, RisingWave calls `catalog.create_namespace`; if that call fails the error is wrapped in `SinkError::Iceberg` and annotated with `failed to create iceberg namespace: {namespace}`. It means the catalog backend rejected or failed the namespace creation request.
Source
Thrown at src/connector/src/sink/iceberg/create_table.rs:293
namespace: &NamespaceIdent,
) -> Result<()> {
let mut namespaces = vec![namespace.clone()];
let mut parent = namespace.parent();
while let Some(parent_namespace) = parent {
parent = parent_namespace.parent();
namespaces.push(parent_namespace);
}
for namespace in namespaces.into_iter().rev() {
if !catalog
.namespace_exists(&namespace)
.await
.map_err(|e| SinkError::Iceberg(anyhow!(e)))?
{
catalog
.create_namespace(&namespace, HashMap::default())
.await
.map_err(|e| SinkError::Iceberg(anyhow!(e)))
.with_context(|| format!("failed to create iceberg namespace: {namespace}"))?;
}
}
Ok(())
}
const MAP_KEY: &str = "key";
const MAP_VALUE: &str = "value";
fn field_is_compatible(
rw_type: &risingwave_common::types::DataType,
arrow_field: &ArrowField,
) -> anyhow::Result<bool> {
use risingwave_common::types::DataType as RwDataType;
// A Variant is physically an Arrow struct, but its extension metadata makes it a leaf
// Iceberg type. The binding is exclusive in both directions: a plain struct mimickingView on GitHub (pinned to 6469eb736d)
Solutions
- Read the wrapped underlying error for the real cause (permission denied, conflict, etc.).
- Pre-create the namespace manually in the catalog (or with spark/trino) with correct permissions.
- Check catalog credentials/ACLs allow namespace creation.
- If it's a race, re-run the sink creation; the namespace now exists and the check will skip creation.
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-create the namespace via the catalog CLI/API before sinking
// REST: PUT /v1/{prefix}/namespaces/{ns} with {"namespace": ["ns"]} Try / catch
// match on the wrapped catalog error kind
if let Err(e) = create_sink().await {
if e.to_string().contains("failed to create iceberg namespace") {
log::error!("namespace creation failed; check ACLs: {e:#}");
}
} Prevention
- Grant the sink's credentials namespace-create permissions on the catalog.
- Pre-create namespaces with your infrastructure tooling so sink creation only handles the table.
- Avoid concurrent sink creations targeting the same new namespace.
When it happens
Trigger: Called from `create_table_if_not_exists_impl` (via `create_namespace_if_not_exists`) when `catalog.create_namespace(&namespace, HashMap::default())` returns Err during Iceberg sink table creation.
Common situations: Insufficient permissions on the catalog to create namespaces; namespace already exists but `namespace_exists` gave a stale/false negative (eventual consistency or race with another writer); invalid namespace characters for the catalog backend.
Related errors
- Snowflake catalog only supports iceberg sources
- `catalog.type` must be set
- Failed to list iceberg namespaces.
- Failed to create namespace.
- Failed to check namespace exists.
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/1ae5239c526db65b.
Report an issue: GitHub.