{"record":{"id":"eaba4f1be786e0d3","repo":"risingwavelabs/risingwave","slug":"invalid-iceberg-snapshot-timestamp","errorCode":null,"errorMessage":"invalid Iceberg snapshot timestamp","messagePattern":"invalid Iceberg snapshot timestamp","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/iceberg/metadata.rs","lineNumber":155,"sourceCode":") -> ConnectorResult<Option<DataChunk>> {\n    Ok(builder.append_one_row(row.into_owned_row()))\n}\n\n/// Read one Iceberg metadata relation and emit bounded [`DataChunk`]s.\n#[try_stream(ok = DataChunk, error = ConnectorError)]\npub async fn scan_iceberg_metadata(\n    table: Table,\n    metadata_type: IcebergMetadataTableType,\n    time_travel_info: Option<IcebergTimeTravelInfo>,\n    chunk_size: usize,\n) {\n    let mut builder = DataChunkBuilder::new(metadata_type.schema().data_types(), chunk_size);\n\n    match metadata_type {\n        IcebergMetadataTableType::Snapshots => {\n            for snapshot in table.metadata().snapshots() {\n                let committed_at = Timestamptz::from_millis(snapshot.timestamp_ms())\n                    .ok_or_else(|| anyhow!(\"invalid Iceberg snapshot timestamp\"))?;\n                let summary =\n                    serde_json::to_value(&snapshot.summary().additional_properties)?.into();\n                let row = IcebergSnapshotRow {\n                    committed_at,\n                    snapshot_id: snapshot.snapshot_id(),\n                    parent_id: snapshot.parent_snapshot_id(),\n                    sequence_number: snapshot.sequence_number(),\n                    operation: snapshot.summary().operation.as_str().to_owned(),\n                    manifest_list: snapshot.manifest_list().to_owned(),\n                    summary,\n                };\n                if let Some(chunk) = append_row(&mut builder, row)? {\n                    yield chunk;\n                }\n            }\n        }\n        IcebergMetadataTableType::Manifests | IcebergMetadataTableType::Files => {\n            let Some(snapshot_id) =","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/iceberg/metadata.rs#L137-L173","documentation":"When scanning the iceberg_snapshots metadata table, each snapshot's timestamp_ms is converted to a Timestamptz; a None result (invalid milliseconds) aborts the scan with this error rather than emitting a row with a NULL committed_at.","triggerScenarios":"Querying the snapshot metadata table of an Iceberg table whose metadata contains a snapshot with a timestamp_ms value that cannot produce a valid Timestamptz (out of range millis).","commonSituations":"Corrupted or hand-edited Iceberg metadata JSON, or snapshots written by a buggy external writer with out-of-range timestamps.","solutions":["Inspect the table's metadata JSON (v*.metadata.json) for snapshots with invalid 'timestamp-ms'","Repair or regenerate the metadata from a valid snapshot/backup","Query other metadata tables or snapshot history via Iceberg tools to locate the bad snapshot"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"let ts_ok = snapshots.iter().all(|s| Timestamptz::from_millis(s.timestamp_ms()).is_some());","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"invalid Iceberg snapshot timestamp\") => {\n        // skip or repair the offending snapshot metadata\n    }\n    other => other?,\n}","preventionTips":["Do not hand-edit Iceberg metadata JSON","Use spec-compliant writers for snapshots"],"tags":["iceberg","metadata","timestamp"],"backgroundTag":"invalid-date-format","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}