risingwavelabs/risingwave · error

Cannot find the snapshot id in the iceberg table.

Error message

Cannot find the snapshot id in the iceberg table.

What it means

When time travel to a specific snapshot version is requested for an Iceberg source, `get_snapshot_id_from_metadata` looks up the requested snapshot id in the table metadata via `snapshot_by_id`. If the metadata contains no snapshot with that id, the function bails with this error. It means the requested snapshot does not exist (or no longer exists) in the current table metadata.

Source

Thrown at src/connector/src/source/iceberg/mod.rs:313

    pub schema: std::sync::Arc<iceberg::spec::Schema>,
}

impl IcebergSplitEnumerator {
    pub fn get_snapshot_id(
        table: &Table,
        time_travel_info: Option<IcebergTimeTravelInfo>,
    ) -> ConnectorResult<Option<i64>> {
        Self::get_snapshot_id_from_metadata(table.metadata(), time_travel_info)
    }

    fn get_snapshot_id_from_metadata(
        metadata: &TableMetadata,
        time_travel_info: Option<IcebergTimeTravelInfo>,
    ) -> ConnectorResult<Option<i64>> {
        let snapshot_id = match time_travel_info {
            Some(IcebergTimeTravelInfo::Version(version)) => {
                let Some(snapshot) = metadata.snapshot_by_id(version) else {
                    bail!("Cannot find the snapshot id in the iceberg table.");
                };
                Some(snapshot.snapshot_id())
            }
            Some(IcebergTimeTravelInfo::TimestampMs(timestamp)) => {
                let snapshot_log = metadata
                    .history()
                    .iter()
                    .rev()
                    .find(|snapshot_log| snapshot_log.timestamp_ms() <= timestamp);
                match snapshot_log {
                    Some(snapshot_log) => Some(snapshot_log.snapshot_id),
                    None => {
                        // convert unix time to human-readable time
                        let time = chrono::DateTime::from_timestamp_millis(timestamp);
                        if let Some(time) = time {
                            tracing::warn!("Cannot find a snapshot older than {}", time);
                        } else {
                            tracing::warn!("Cannot find a snapshot");

View on GitHub (pinned to 6469eb736d)

Solutions

  1. List current table snapshots (iceberg metadata) and use an existing snapshot id.
  2. Re-create or update the source with a valid/current snapshot version.
  3. If targeting a point in time, switch to timestamp-based time travel (`IcebergTimeTravelInfo::TimestampMs`) instead of a fixed snapshot id.
  4. Check that expire-snapshot jobs have not removed the snapshot; increase retention if needed.

Example fix

// before
{"iceberg.time_travel.version": "87241518739178"}
// after: use a snapshot id present in current metadata
{"iceberg.time_travel.version": "<id from SELECT * FROM table.snapshots>"}
Defensive patterns

Strategy: validation

Validate before calling

let exists = metadata.snapshot_by_id(requested_version).is_some();
if !exists {
    // pick a valid snapshot from metadata.snapshots() or fall back to latest
}

Type guard

fn snapshot_exists(m: &TableMetadata, id: i64) -> bool { m.snapshot_by_id(id).is_some() }

Try / catch

match get_snapshot_id_from_metadata(&metadata, travel_info) {
    Ok(id) => id,
    Err(e) if e.to_string().contains("Cannot find the snapshot id") => {
        // fall back to current snapshot or refresh the configured version
        None
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Querying a `CREATE SOURCE ... WITH (time travel)`/scan with `IcebergTimeTravelInfo::Version(v)` where `v` is not a snapshot id present in `TableMetadata::snapshot_by_id` — e.g. a stale, typo'd, or expired (retention-expired) snapshot id.

Common situations: Using a snapshot id captured from an older table state that has since been rewritten; referencing a snapshot removed by expire_snapshots; typo in the version configured in source properties; pointing a source at a different table than the snapshot belongs to.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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