risingwavelabs/risingwave · error · SinkError::Iceberg

Invalid commit metadata: empty payload

Error message

Invalid commit metadata: empty payload

What it means

commit_data deserializes accumulated commit metadata via deserialize_metadata into a Vec<Vec<u8>> payload list. An empty list means no write result (and no trailing snapshot id) was collected for this commit, so there is nothing to commit; the code returns this SinkError::Iceberg instead of proceeding to the Iceberg table commit.

Source

Thrown at src/connector/src/sink/iceberg/commit.rs:491

            "iceberg_sink_commit_started",
        );

        if commit_metadata.is_empty() {
            tracing::debug!(
                iceberg_component = "sink_committer",
                iceberg_operation = "commit",
                sink_id = %self.sink_id,
                table = %self.table.identifier(),
                epoch,
                "iceberg_sink_commit_skipped_empty_metadata",
            );
            return Ok(());
        }

        // Deserialize commit metadata
        let mut payload = deserialize_metadata(commit_metadata);
        if payload.is_empty() {
            return Err(SinkError::Iceberg(anyhow!(
                "Invalid commit metadata: empty payload"
            )));
        }

        // Last element is snapshot_id
        let snapshot_id_bytes = payload.pop().ok_or_else(|| {
            SinkError::Iceberg(anyhow!("Invalid commit metadata: missing snapshot_id"))
        })?;
        let snapshot_id = i64::from_le_bytes(
            snapshot_id_bytes
                .try_into()
                .map_err(|_| SinkError::Iceberg(anyhow!("Invalid snapshot id bytes")))?,
        );

        // Remaining elements are write_results
        let write_results = payload
            .into_iter()
            .map(|p| IcebergCommitResult::try_from_serialized_bytes(&p))

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Ensure at least one write result is attached before invoking commit (check upstream guards that short-circuit on empty input)
  2. Verify the two-phase/single-phase coordinator forwards collected metadata on commit
  3. Inspect why deserialize_metadata returned an empty vec (corrupt vs genuinely empty input)
Defensive patterns

Strategy: validation

Validate before calling

fn commit_metadata_ready(items: &[Vec<u8>]) -> bool {
    !items.is_empty()
}

Try / catch

if commit_metadata.is_empty() {
    tracing::warn!("no commit metadata; skipping commit");
    return Ok(());
}
commit_data(commit_metadata).await?;

Prevention

When it happens

Trigger: commit_data invoked with an empty commit_metadata collection — e.g. the two-phase coordinator fires a commit without any preceding write results, or all metadata was filtered out upstream (the preceding `if ... return Ok(())` guard did not catch it).

Common situations: Coordinator/actor bugs where write results were never forwarded; state-store reads returning empty; sink epochs committed out of order.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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