apache/iceberg · error · java.lang.UnsupportedOperationException
SparkCachedTableCatalog does not support listing tables
Error message
SparkCachedTableCatalog does not support listing tables
What it means
Capability guard in SparkCachedTableCatalog.listTables: this internal catalog only resolves cached table loads (e.g. snapshot/branch/tag time-trap identifiers) and has no table listing. The message names the class; the failure is structural, not data-dependent.
Source
Thrown at spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/SparkCachedTableCatalog.java:62
/** An internal table catalog that is capable of loading tables from a cache. */
public class SparkCachedTableCatalog implements TableCatalog, SupportsFunctions {
private static final String CLASS_NAME = SparkCachedTableCatalog.class.getName();
private static final Splitter COMMA = Splitter.on(",");
private static final Pattern AT_TIMESTAMP = Pattern.compile("at_timestamp_(\\d+)");
private static final Pattern SNAPSHOT_ID = Pattern.compile("snapshot_id_(\\d+)");
private static final Pattern BRANCH = Pattern.compile("branch_(.*)");
private static final Pattern TAG = Pattern.compile("tag_(.*)");
private static final String REWRITE = "rewrite";
private static final SparkTableCache TABLE_CACHE = SparkTableCache.get();
private String name = null;
@Override
public Identifier[] listTables(String[] namespace) {
throw new UnsupportedOperationException(CLASS_NAME + " does not support listing tables");
}
@Override
public SparkTable loadTable(Identifier ident) throws NoSuchTableException {
return load(ident);
}
@Override
public SparkTable loadTable(Identifier ident, String version) throws NoSuchTableException {
SparkTable table = load(ident);
Preconditions.checkArgument(
table.snapshotId() == null, "Cannot time travel based on both table identifier and AS OF");
return table.copyWithSnapshotId(Long.parseLong(version));
}
@Override
public SparkTable loadTable(Identifier ident, long timestampMicros) throws NoSuchTableException {
SparkTable table = load(ident);View on GitHub (pinned to 86d9c8fc54)
Solutions
- List tables in the underlying real catalog (spark_catalog or the Iceberg catalog) instead
- Avoid invoking listTables on the cached-table catalog; cache lookups go through loadTable only
- Guard catalog-listing tooling to skip non-listable catalogs
Example fix
// before
catalogManager.catalog("spark_catalog_cached").asTableCatalog().listTables(ns);
// after
TableCatalog real = catalogManager.catalog("spark_catalog").asTableCatalog();
Identifier[] tables = real.listTables(ns); Defensive patterns
Strategy: try-catch
Validate before calling
if (catalog instanceof SparkCachedTableCatalog) { /* skip listing, use real catalog */ } Type guard
boolean isListable(Catalog catalog) { return !(catalog instanceof SparkCachedTableCatalog); } Try / catch
try { return catalog.listTables(namespace); } catch (UnsupportedOperationException e) { return realCatalog.listTables(namespace); } Prevention
- Skip cache-backed catalogs when enumerating catalog contents
- List from the underlying catalog instead
- Document cached-table catalogs as non-listable in tooling
When it happens
Trigger: Calling SHOW TABLES / listTables against a namespace in the SparkCachedTableCatalog (the catalog used for cached tables, named like spark_catalog_cached or accessed through cached table identifiers).
Common situations: Exploring catalogs in a SQL client and listing all namespaces/tables; tools that enumerate catalog contents encounter this read-only cache catalog.
Related errors
- SparkCachedTableCatalog does not support table invalidation
- does not support table invalidation
- Cannot use catalog %s(%s): not a TableCatalog
- SparkCachedTableCatalog does not support creating tables
- SparkCachedTableCatalog does not support altering tables
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/8c7a229ae11291bd.
Report an issue: GitHub.