apache/iceberg · error · IllegalArgumentException
Unknown time travel: " + timeTravel
Error message
Unknown time travel: " + timeTravel
What it means
SparkTable.create resolves time travel specifications from Spark's TIME TRAVEL spec; it supports no time travel, AsOfVersion, and AsOfTimestamp. Any other TimeTravel spec instance is rejected with IllegalArgumentException, meaning Spark produced a time travel expression Iceberg does not recognize.
Solutions
- Use the supported syntax: `VERSION AS OF` / `TIMESTAMP AS OF` (or `FOR VERSION AS OF` / `FOR TIMESTAMP AS OF`).
- Check Spark and Iceberg versions are compatible (spark/v4.1 module expects Spark 4.1).
- Pass a plain table or an AsOfVersion/AsOfTimestamp when calling SparkTable.create programmatically.
- Upgrade Iceberg if the Spark version introduced new TimeTravel variants.
Example fix
// before
spark.read.option("as-of", something).table("db.tbl")
// after
spark.read.table("db.tbl").option("version-as-of", "1234567890") // or
spark.sql("SELECT * FROM db.tbl VERSION AS OF 1234567890") Defensive patterns
Strategy: validation
Validate before calling
if (timeTravel != null && !(timeTravel instanceof AsOfVersion) && !(timeTravel instanceof AsOfTimestamp)) { throw new IllegalArgumentException("unsupported time travel: " + timeTravel); } Type guard
boolean supported = timeTravel == null || timeTravel instanceof AsOfVersion || timeTravel instanceof AsOfTimestamp;
Try / catch
try { return SparkTable.create(table, timeTravel); } catch (IllegalArgumentException e) { throw new AnalysisException("Use VERSION AS OF or TIMESTAMP AS OF", e); } Prevention
- Use standard VERSION AS OF / TIMESTAMP AS OF syntax
- Pin compatible Spark and Iceberg versions
- Avoid wrapping TimeTravel specs in custom subclasses
When it happens
Trigger: CREATE TABLE ... AS / DataFrame read with VERSION AS OF or TIMESTAMP AS OF that resolves to an unexpected TimeTravel subtype passed to SparkTable.create(table, timeTravel).
Common situations: Spark version mismatches where new time travel specs exist; custom catalog/planner wrappers producing a non-standard TimeTravel implementation; using snapshot-id-based travel through an unsupported syntax variant.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- AS OF is not supported for changelogs
- AS OF is not supported for changelogs
- Cannot pass path based identifier to
- Cannot pass path based identifier to
- Cannot pass path based identifier to
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/c01040969d352e4d.
Report an issue: GitHub.
Appendix: source
Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/source/SparkTable.java:332
}
public static SparkTable create(Table table, String branch) {
ValidationException.check(
branch == null || SnapshotRef.MAIN_BRANCH.equals(branch) || table.snapshot(branch) != null,
"Cannot use branch (does not exist): %s",
branch);
return new SparkTable(table, branch);
}
public static SparkTable create(Table table, TimeTravel timeTravel) {
if (timeTravel == null) {
return new SparkTable(table);
} else if (timeTravel instanceof AsOfVersion asOfVersion) {
return createWithVersion(table, asOfVersion);
} else if (timeTravel instanceof AsOfTimestamp asOfTimestamp) {
return createWithTimestamp(table, asOfTimestamp);
} else {
throw new IllegalArgumentException("Unknown time travel: " + timeTravel);
}
}
private static SparkTable createWithVersion(Table table, AsOfVersion timeTravel) {
if (timeTravel.isSnapshotId()) {
return new SparkTable(table, Long.parseLong(timeTravel.version()), timeTravel);
} else {
SnapshotRef ref = table.refs().get(timeTravel.version());
Preconditions.checkArgument(
ref != null,
"Cannot find matching snapshot ID or reference name for version %s",
timeTravel.version());
if (ref.isBranch()) {
return new SparkTable(table, timeTravel.version());
} else {
return new SparkTable(table, ref.snapshotId(), timeTravel);
}
}View on GitHub (pinned to 86d9c8fc54)