risingwavelabs/risingwave · error · SinkError

Iceberg error

Error message

Iceberg error: {0}

What it means

A `SinkError::Iceberg` variant built from an `anyhow::Error`. RisingWave's Iceberg sink throws this whenever the underlying `icelake`/iceberg writer or catalog operations fail; the display string is "Iceberg error: {0}" and the cause chain plus backtrace are preserved. It is a generic umbrella for all Iceberg-data-path failures in the sink.

Solutions

  1. Read the wrapped anyhow message and its `source` chain — it points to the failing stage (catalog open, parquet write, commit).
  2. Verify catalog properties in the sink `WITH` options (catalog type, URI, warehouse, namespace, table) and the object-store credentials/endpoint.
  3. Compare the sink's derived schema with the target Iceberg table schema; drop/recreate or evolve the table so they match.
  4. Retry or investigate commit failures — concurrent writers can conflict; ensure only expected writers commit to the table.
Defensive patterns

Strategy: try-catch

Validate before calling

async fn check_iceberg_target(catalog: &dyn Catalog, ns: &str, table: &str) -> anyhow::Result<()> {
    let identifiers = catalog.list_tables(&NamespaceIdent::from_str(ns)?).await?;
    anyhow::ensure!(identifiers.iter().any(|t| t.name() == table), "iceberg table {ns}.{table} not found");
    Ok(())
}

Type guard

fn as_iceberg_error(err: &SinkError) -> Option<&anyhow::Error> {
    if let SinkError::Iceberg(e) = err { Some(e) } else { None }
}

Try / catch

match sink.commit().await {
    Err(SinkError::Iceberg(e)) => {
        log::error!("iceberg failure: {e:#}"); // full cause chain
        // classify: config vs transient commit conflict, then retry or fix config
    }
    Err(e) => return Err(e.into()),
    Ok(_) => {}
}

Prevention

When it happens

Trigger: Writing records to an Iceberg table from the sink: opening the table via the catalog, building/writing parquet data files, committing snapshots (commits to the catalog), or any `icelake` API returning an error that the sink converts with `.into()`/`anyhow!`.

Common situations: Wrong catalog configuration (REST/Hive/Glue catalog URL, warehouse path, credentials); S3/object-store misconfiguration (endpoint, region, bucket permissions); schema mismatch between the RisingWave sink plan and the existing Iceberg table schema; concurrent commit conflicts or stale metadata after table evolution.

Related errors


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

Appendix: source

Thrown at src/connector/src/sink/mod.rs:1108

    #[error("Kafka error: {0}")]
    Kafka(#[from] rdkafka::error::KafkaError),
    #[error("Kinesis error: {0}")]
    Kinesis(
        #[source]
        #[backtrace]
        anyhow::Error,
    ),
    #[error("Remote sink error: {0}")]
    Remote(
        #[source]
        #[backtrace]
        anyhow::Error,
    ),
    #[error("Encode error: {0}")]
    Encode(String),
    #[error("Avro error: {0}")]
    Avro(#[from] apache_avro::Error),
    #[error("Iceberg error: {0}")]
    Iceberg(
        #[source]
        #[backtrace]
        anyhow::Error,
    ),
    #[error("config error: {0}")]
    Config(
        #[source]
        #[backtrace]
        anyhow::Error,
    ),
    #[error("coordinator error: {0}")]
    Coordinator(
        #[source]
        #[backtrace]
        anyhow::Error,
    ),
    #[error("ClickHouse error: {0}")]

View on GitHub (pinned to 6469eb736d)