risingwavelabs/risingwave · error

Iceberg value exceeds INTEGER

Error message

Iceberg {field} value {value} exceeds INTEGER

What it means

u32 values from Iceberg metadata (e.g. manifest fields like snapshot counts or sequence numbers stored as u32) are converted to i32 for the INTEGER-typed metadata column. If the u32 value exceeds i32::MAX, conversion fails with this error.

Solutions

  1. Check the manifest file for corrupted/abnormal values
  2. Rebuild or rewrite the affected manifest list/metadata
  3. Report upstream if a valid Iceberg table triggers it
Defensive patterns

Strategy: try-catch

Validate before calling

if v > i32::MAX as u32 { return Err("u32 value exceeds INTEGER"); }

Type guard

fn fits_i32(v: u32) -> bool { v <= i32::MAX as u32 }

Try / catch

match result {
    Err(e) if e.to_string().contains("exceeds INTEGER") => log::warn!("metadata u32 out of i32 range"),
    other => other?,
}

Prevention

When it happens

Trigger: Scanning iceberg_manifests metadata table where a u32 field value is above 2,147,483,647.

Common situations: Rare; requires a manifest with an extremely large u32 metric value, usually from corruption or synthetic data.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at src/connector/src/sink/iceberg/metadata.rs:129

    content_size_in_bytes: Option<i64>,
}

fn to_i64(value: u64, field: &'static str) -> ConnectorResult<i64> {
    value
        .try_into()
        .map_err(|_| anyhow!("Iceberg {field} value {value} exceeds BIGINT").into())
}

fn optional_u64_to_i64(value: Option<u64>, field: &'static str) -> ConnectorResult<Option<i64>> {
    value.map(|value| to_i64(value, field)).transpose()
}

fn optional_u32_to_i32(value: Option<u32>, field: &'static str) -> ConnectorResult<Option<i32>> {
    value
        .map(|value| {
            value
                .try_into()
                .map_err(|_| anyhow!("Iceberg {field} value {value} exceeds INTEGER").into())
        })
        .transpose()
}

fn append_row(
    builder: &mut DataChunkBuilder,
    row: impl Fields,
) -> ConnectorResult<Option<DataChunk>> {
    Ok(builder.append_one_row(row.into_owned_row()))
}

/// Read one Iceberg metadata relation and emit bounded [`DataChunk`]s.
#[try_stream(ok = DataChunk, error = ConnectorError)]
pub async fn scan_iceberg_metadata(
    table: Table,
    metadata_type: IcebergMetadataTableType,
    time_travel_info: Option<IcebergTimeTravelInfo>,
    chunk_size: usize,

View on GitHub (pinned to 6469eb736d)