risingwavelabs/risingwave · error
Unsupported version string in iceberg time travel
Error message
Unsupported version string in iceberg time travel
What it means
to_iceberg_time_travel_as_of maps an AsOf clause to IcebergTimeTravelInfo. Iceberg time travel supports numeric snapshot versions and timestamps, but a string version (AsOf::VersionString) is not supported, so the function bails with this error.
Solutions
- Use a numeric snapshot ID: AS OF VERSION 1234567890.
- Look up the numeric snapshot ID from the Iceberg metadata and pass it unquoted.
- Use AS OF TIMESTAMP with an RFC3339 string if you want time-based travel instead of version-based.
Example fix
// before SELECT * FROM iceberg_table AS OF VERSION '1234567890'; // after SELECT * FROM iceberg_table AS OF VERSION 1234567890;
Defensive patterns
Strategy: validation
Validate before calling
// ensure Iceberg snapshot version is numeric before query
let version: i64 = snapshot_id.parse().expect("AS OF VERSION must be numeric for Iceberg"); Type guard
fn is_numeric_version(s: &str) -> bool { s.parse::<i64>().is_ok() } Try / catch
match res {
Err(e) if e.to_string().contains("Unsupported version string") => eprintln!("Iceberg time travel requires a numeric AS OF VERSION; use AS OF TIMESTAMP for time-based travel"),
other => other?,
} Prevention
- Never quote Iceberg snapshot IDs in AS OF VERSION.
- Resolve snapshot IDs from Iceberg metadata before querying.
- Prefer AS OF TIMESTAMP for human-facing time travel.
When it happens
Trigger: Querying an Iceberg table/metadata table with AS OF VERSION '<string>' where the version is a quoted string rather than a number, e.g. AS OF VERSION 'v3' or AS OF VERSION '123' (string-typed).
Common situations: Users referencing snapshots by name or by quoted snapshot IDs; SQL drivers that pass version literals as strings; documentation examples using string versions.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- bounded compaction is not supported for copy-on-write tasks
- Cannot find the snapshot id in the iceberg table.
- Iceberg metadata relations are not supported in streaming…
- Snowflake catalog only supports iceberg sources
- support negative scale for arrow decimal
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/bb6c6074ceef2f4d.
Report an issue: GitHub.
Appendix: source
Thrown at src/frontend/src/optimizer/plan_node/utils.rs:585
.ok_or_else(|| anyhow!("invalid timestamp"))?
}
};
Ok(Some(PbBatchQueryEpoch {
epoch: Some(batch_query_epoch::PbEpoch::TimeTravel(
unix_timestamp_sec_to_epoch(timestamp).0,
)),
}))
}
pub fn to_iceberg_time_travel_as_of(
a: &Option<AsOf>,
timezone: &String,
) -> Result<Option<IcebergTimeTravelInfo>> {
Ok(match a {
Some(AsOf::VersionNum(v)) => Some(IcebergTimeTravelInfo::Version(*v)),
Some(AsOf::TimestampNum(ts)) => Some(IcebergTimeTravelInfo::TimestampMs(ts * 1000)),
Some(AsOf::VersionString(_)) => {
bail!("Unsupported version string in iceberg time travel")
}
Some(AsOf::TimestampString(ts)) => {
let date_time = speedate::DateTime::parse_str_rfc3339(ts)
.map_err(|_e| anyhow!("failed to parse the timestamp"))?;
let timestamp = if date_time.time.tz_offset.is_none() {
// If the input does not specify a time zone, use the time zone set by the "SET TIME ZONE" command.
let tz = Timestamptz::lookup_time_zone(timezone).map_err(|e| anyhow!(e))?;
match tz.with_ymd_and_hms(
date_time.date.year.into(),
date_time.date.month.into(),
date_time.date.day.into(),
date_time.time.hour.into(),
date_time.time.minute.into(),
date_time.time.second.into(),
) {
MappedLocalTime::Single(d) => Ok(d.timestamp()),
MappedLocalTime::Ambiguous(_, _) | MappedLocalTime::None => {
Err(anyhow!(format!(View on GitHub (pinned to 6469eb736d)