apache/iceberg · error · UnsupportedOperationException
does not support table invalidation
Error message
does not support table invalidation
What it means
SparkRewriteTableCatalog.invalidateTable(ident) always throws UnsupportedOperationException because the catalog does not own table metadata (it reads from a short-lived cache); there is nothing to invalidate and cache eviction is managed by the rewrite machinery.
Source
Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/SparkRewriteTableCatalog.java:71
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");
}
@Override
public SparkTable alterTable(Identifier ident, TableChange... changes) {
throw new UnsupportedOperationException(CLASS_NAME + " does not support altering tables");
}
@Override
public boolean dropTable(Identifier ident) {
throw new UnsupportedOperationException(CLASS_NAME + " does not support dropping tables");
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Do not call invalidateTable on the rewrite catalog; it holds no authoritative table state.
- Invalidate on the real catalog (SparkCatalog.invalidateTable) if a refresh is needed.
- Let the rewrite procedure's SparkTableCache lifecycle manage entry freshness.
Example fix
// before rewriteCatalog.invalidateTable(ident); // after sparkCatalog.invalidateTable(ident); // refresh via the real catalog
Defensive patterns
Strategy: type-guard
Validate before calling
if (catalog instanceof SparkRewriteTableCatalog) {
throw new UnsupportedOperationException("invalidateTable not supported on rewrite catalog");
} Type guard
boolean supportsInvalidation(CatalogPlugin c) {
return !(c instanceof SparkRewriteTableCatalog);
} Try / catch
try {
catalog.invalidateTable(ident);
} catch (UnsupportedOperationException e) {
realCatalog.invalidateTable(ident); // refresh via the authoritative catalog
} Prevention
- Skip invalidation for procedure-scoped catalogs.
- Invalidate on SparkCatalog/HiveCatalog instead.
- Let SparkTableCache manage its own lifecycle.
- Avoid generic refresh code that assumes all catalogs support invalidation.
When it happens
Trigger: Calling invalidateTable(ident) on SparkRewriteTableCatalog directly, or Spark's session catalog cache refresh logic probing this catalog after DML.
Common situations: Framework code that invalidates cached tables generically across all registered catalogs; manual cache-busting attempts against the rewrite catalog.
Related errors
- does not support table invalidation
- org.apache.iceberg.spark.SparkRewriteTableCatalog does not s
- Table not found: ${ident}
- org.apache.iceberg.spark.SparkRewriteTableCatalog does not s
- does not support time travel
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/f65bed138eb1959c.
Report an issue: GitHub.