risingwavelabs/risingwave · error · SinkError::Iceberg
failed to create iceberg table
Error message
failed to create iceberg table
What it means
This is the final step of table creation: catalog.create_table(&namespace, table_creation). Any failure returned by the catalog (namespace missing, permission denied, table already created concurrently, invalid location, storage errors) is wrapped into SinkError::Iceberg with the context 'failed to create iceberg table'.
Source
Thrown at src/connector/src/sink/iceberg/create_table.rs:268
.location(location)
.sort_order(sort_order)
.build(),
(Some(location), None, None) => table_creation_builder.location(location).build(),
(None, Some(partition_spec), Some(sort_order)) => table_creation_builder
.partition_spec(partition_spec)
.sort_order(sort_order)
.build(),
(None, Some(partition_spec), None) => table_creation_builder
.partition_spec(partition_spec)
.build(),
(None, None, Some(sort_order)) => table_creation_builder.sort_order(sort_order).build(),
(None, None, None) => table_creation_builder.build(),
};
catalog
.create_table(&namespace, table_creation)
.await
.map_err(|e| SinkError::Iceberg(anyhow!(e)))
.context("failed to create iceberg table")?;
Ok(true)
}
async fn create_namespace_if_not_exists(
catalog: &dyn Catalog,
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)View on GitHub (pinned to 6469eb736d)
Solutions
- Inspect the chained underlying error for the catalog's response (auth, permission, location).
- Verify the table location's bucket/prefix exists and RisingWave's credentials can write to it.
- Confirm the namespace exists (create_namespace_if_not_exists ran successfully) and wasn't removed concurrently.
- Retry if the failure is transient; if the table was created concurrently, the existing table will be validated instead.
Example fix
// before: IAM role lacks s3:PutObject on the location WITH (connector='iceberg', warehouse='s3://bucket/iceberg/', s3.access.key='...', ...) // after: grant write permissions on the bucket/prefix or fix the access key aws s3api put-object --bucket bucket --key iceberg/test --body /dev/null # verify write access first
Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight: verify write access to the target location and namespace existence catalog.namespace_exists(&namespace).await?; // and verify storage credentials, e.g.: aws s3api put-object --bucket my-bucket --key iceberg/.write-test --body /dev/null
Try / catch
match catalog.create_table(&namespace, table_creation).await {
Err(e) if is_retryable(&e) => retry_with_backoff(3, || create_table(...)),
Err(e) => Err(SinkError::Iceberg(anyhow!(e)).context("failed to create iceberg table")),
Ok(t) => Ok(t),
} Prevention
- Verify object-store credentials have write permission on the warehouse prefix before creating sinks.
- Ensure create_namespace_if_not_exists succeeded and the namespace isn't deleted concurrently.
- Handle the table-exists race by falling back to validation of the existing table.
- Monitor catalog/storage availability and retry transient failures.
When it happens
Trigger: create_table_if_not_exists_impl reaches catalog.create_table and the catalog client returns Err — e.g. the namespace does not exist and creation failed, the location bucket is not writable, credentials lack permission, or a concurrent process created the table between the table_exists check and create.
Common situations: Object storage credentials/permissions misconfigured; namespace was deleted between create_namespace_if_not_exists and create_table; REST catalog rejecting the request (quota, schema conflicts); transient catalog/storage outages.
Related errors
- {e}
- Sink not found: {}
- distribution key {:?} must be a subset of primary key {:?}
- `catalog.type` must be set
- Failed to list iceberg namespaces.
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/666cb9e718e3ab99.
Report an issue: GitHub.