apache/iceberg · error · IllegalArgumentException
Unknown Spark table type:
Error message
Unknown Spark table type:
What it means
Thrown by SparkCatalog.loadTable(ident, version) when the loaded table is neither a SparkTable nor a SparkChangelogTable, i.e. the catalog produced an unrecognized Table implementation. This indicates an internal invariant violation or a custom table type the catalog adapter does not know how to time-travel.
Source
Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/SparkCatalog.java:215
} catch (NumberFormatException e) {
SnapshotRef ref = sparkTable.table().refs().get(version);
ValidationException.check(
ref != null,
"Cannot find matching snapshot ID or reference name for version %s",
version);
if (ref.isBranch()) {
return sparkTable.copyWithBranch(version);
} else {
return sparkTable.copyWithSnapshotId(ref.snapshotId());
}
}
} else if (table instanceof SparkChangelogTable) {
throw new UnsupportedOperationException("AS OF is not supported for changelogs");
} else {
throw new IllegalArgumentException("Unknown Spark table type: " + table.getClass().getName());
}
}
@Override
public Table loadTable(Identifier ident, long timestamp) throws NoSuchTableException {
Table table = loadTable(ident);
if (table instanceof SparkTable) {
SparkTable sparkTable = (SparkTable) table;
Preconditions.checkArgument(
sparkTable.snapshotId() == null && sparkTable.branch() == null,
"Cannot do time-travel based on both table identifier and AS OF");
// convert the timestamp to milliseconds as Spark passes microseconds
// but Iceberg uses milliseconds for snapshot timestamps
long timestampMillis = TimeUnit.MICROSECONDS.toMillis(timestamp);
long snapshotId = SnapshotUtil.snapshotIdAsOfTime(sparkTable.table(), timestampMillis);View on GitHub (pinned to 86d9c8fc54)
Solutions
- Verify you are using the stock org.apache.iceberg.spark.SparkCatalog, not a custom subclass that returns foreign Table implementations.
- Report the table class name in the message — check whether your catalog wrapper is inserting a custom Table implementation.
- Upgrade Iceberg; a new wrapper type may have been added upstream and fixed in a later release.
- If you own a subclass, override loadTable(ident, version) to handle your table type.
Defensive patterns
Strategy: try-catch
Validate before calling
Table t = catalog.loadTable(ident);
if (!(t instanceof SparkTable) && !(t instanceof SparkChangelogTable)) {
throw new IllegalStateException("Unsupported table type for time travel: " + t.getClass().getName());
} Type guard
boolean supportsTimeTravel(org.apache.spark.sql.connector.catalog.Table t) {
return t instanceof org.apache.iceberg.spark.SparkTable;
} Try / catch
try {
return catalog.loadTable(ident, version);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Unknown Spark table type")) {
throw new UnsupportedOperationException("Time travel unavailable for " + ident, e);
}
throw e;
} Prevention
- Use the stock SparkCatalog; inspect any subclasses for overridden load() returning foreign Table types.
- After Iceberg upgrades, smoke-test time travel on all catalog types in use.
- Capture the class name from the message to debug custom wrappers.
When it happens
Trigger: Calling loadTable(ident, version) where loadTable(ident) returns a Table object that is not an instance of SparkTable or SparkChangelogTable — practically only possible with a subclassed/custom SparkCatalog overriding load().
Common situations: Custom SparkCatalog subclasses returning their own Table wrappers; internal bugs after Iceberg upgrades introducing new table wrapper types not yet handled in the instanceof chain.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- AS OF is not supported for changelogs
- Unknown time travel: ${timeTravel}
- AS OF is not supported for changelogs
- Unknown Spark table type: %s
- org.apache.iceberg.exceptions.AlreadyExistsException:
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/c62a09ed3f1189a9.
Report an issue: GitHub.