apache/iceberg · error · UnsupportedOperationException
org.apache.iceberg.spark.SparkRewriteTableCatalog does not s
Error message
org.apache.iceberg.spark.SparkRewriteTableCatalog does not support time travel
What it means
The version-based loadTable(ident, version) overload on SparkRewriteTableCatalog always throws UnsupportedOperationException because the rewrite catalog operates on the live cached table and cannot resolve versioned (snapshot-id/branch/tag) loads.
Source
Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/SparkRewriteTableCatalog.java:61
}
@Override
public SparkRewriteTable loadTable(Identifier ident) throws NoSuchTableException {
validateNoNamespace(ident);
String groupId = ident.name();
Table table = TABLE_CACHE.get(groupId);
if (table == null) {
throw new NoSuchTableException(ident);
}
return new SparkRewriteTable(table, groupId);
}
@Override
public SparkTable loadTable(Identifier ident, String version) throws NoSuchTableException {
throw new UnsupportedOperationException(CLASS_NAME + " does not support time travel");
}
@Override
public SparkTable loadTable(Identifier ident, long timestampMicros) throws NoSuchTableException {
throw new UnsupportedOperationException(CLASS_NAME + " does not support time travel");
}
@Override
public void invalidateTable(Identifier ident) {
throw new UnsupportedOperationException(CLASS_NAME + " does not support table invalidation");
}
@Override
public SparkTable createTable(Identifier ident, TableInfo tableInfo)
throws TableAlreadyExistsException {
throw new UnsupportedOperationException(CLASS_NAME + " does not support creating tables");
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Do not time travel with the rewrite catalog; rewrite always operates on the current table state.
- Load the historical snapshot via the regular SparkCatalog: SELECT ... VERSION AS OF, then perform other operations on it.
- Remove version/timestamp options from procedure calls targeting the rewrite catalog.
Example fix
// before Table t = rewriteCatalog.loadTable(ident, "hist-tag"); // after Table t = sparkCatalog.loadTable(ident, "hist-tag"); // versioned loads go through the real catalog
Defensive patterns
Strategy: validation
Validate before calling
if (catalog instanceof SparkRewriteTableCatalog && version != null) {
throw new IllegalArgumentException("Time travel is not supported by SparkRewriteTableCatalog");
} Type guard
boolean supportsTimeTravel(CatalogPlugin c) {
return !(c instanceof SparkRewriteTableCatalog);
} Try / catch
try {
Table t = catalog.loadTable(ident, version);
} catch (UnsupportedOperationException e) {
Table t = sparkCatalog.loadTable(ident, version); // versioned loads via the real catalog
} Prevention
- Never pass versionAsOf/time-travel options to rewrite procedures.
- Route time-travel reads to SparkCatalog.
- Capability-check the catalog before versioned loads.
- Rewrite only the current snapshot.
When it happens
Trigger: Calling loadTable(ident, "branch-or-tag") on SparkRewriteTableCatalog, or running a Spark rewrite procedure with time travel / versionAsOf options that force a versioned load.
Common situations: Passing time-travel options (versionAsOf/timestampAsOf) to rewrite or maintenance procedures; generic engine code probing the catalog with the versioned overload.
Related errors
- does not support time travel
- AS OF is not supported for changelogs
- org.apache.iceberg.spark.SparkRewriteTableCatalog does not s
- does not support table invalidation
- does not support creating tables
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/df31343ea3623143.
Report an issue: GitHub.