risingwavelabs/risingwave · error · SinkError::Iceberg
{e}
Error message
{e} What it means
This error wraps a failure from the Iceberg catalog's `table_exists` check. Before creating the table, the code queries the catalog to see whether the table already exists; any catalog-level failure (network, auth, namespace missing, REST error) is wrapped into SinkError::Iceberg with the raw catalog error message.
Source
Thrown at src/connector/src/sink/iceberg/create_table.rs:112
}
/// Returns `true` if this call created the table, `false` if it already existed.
pub(super) async fn create_table_if_not_exists_impl(
config: &IcebergConfig,
param: &SinkParam,
) -> Result<bool> {
let catalog = config.create_catalog().await?;
let table_id = config
.full_table_name()
.context("Unable to parse table name")?;
let namespace = table_id.namespace().clone();
let table_name = table_id.name().to_owned();
create_namespace_if_not_exists(catalog.as_ref(), &namespace).await?;
if catalog
.table_exists(&table_id)
.await
.map_err(|e| SinkError::Iceberg(anyhow!(e)))?
{
return Ok(false);
}
if config.table_format_version() < FormatVersion::V3
&& let Some(column) = param
.columns
.iter()
.find(|column| column.data_type.contains_variant())
{
return Err(SinkError::Config(anyhow!(
"creating an Iceberg table with VARIANT column `{}` requires `format_version = '3'`",
column.name
)));
}
let iceberg_create_table_arrow_convert = IcebergCreateTableArrowConvert::default();
// convert risingwave schema -> arrow schema -> iceberg schemaView on GitHub (pinned to 6469eb736d)
Solutions
- Inspect the wrapped `{e}` message — it is the underlying catalog client error — and fix the root cause (URL, auth, DNS).
- Verify catalog connectivity from the RisingWave host (curl the REST catalog endpoint / check the metastore).
- Confirm catalog.name/uri/authentication options in the sink config are correct for the catalog type.
- Retry if the failure was transient (network blip, catalog restart).
Example fix
// before catalog.name = 'rest', catalog.uri = 'http://iceberg-catalog:8181' // service down // after: fix endpoint/credentials or start the catalog service, then retry CREATE SINK ... WITH (connector='iceberg', catalog.type='rest', catalog.uri='http://correct-host:8181', ...);
Defensive patterns
Strategy: retry
Validate before calling
// Check catalog reachability before creating the sink
curl -sS -o /dev/null -w '%{http_code}' http://iceberg-catalog:8181/v1/config Try / catch
match create_table_if_not_exists(...).await {
Err(SinkError::Iceberg(e)) if is_transient(&e) => retry_with_backoff(3, || create_table_if_not_exists(...)),
other => other?,
} Prevention
- Validate catalog URI and credentials in the sink WITH options before deploying.
- Monitor catalog service health from RisingWave hosts.
- Ensure network egress to the catalog endpoint is allowed.
- Check that the table identifier is valid for the catalog type.
When it happens
Trigger: create_table_if_not_exists_impl calls catalog.table_exists(&table_id) and the catalog returns Err — e.g. the REST/Hive/Glue catalog is unreachable, credentials are invalid, or the namespace does not resolve.
Common situations: Misconfigured catalog URI or credentials in the sink WITH options; network egress blocked from the RisingWave node to the catalog service; catalog service down; table identifier malformed for the catalog type.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- reload iceberg table
- failed to create iceberg table
- Sink not found: {}
- distribution key {:?} must be a subset of primary key {:?}
- `catalog.type` must be set
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/50b9fd22d2597080.
Report an issue: GitHub.