apache/iceberg · error · UnsupportedOperationException

org.apache.iceberg.spark.SparkRewriteTableCatalog does not s

Error message

org.apache.iceberg.spark.SparkRewriteTableCatalog does not support listing tables

What it means

SparkRewriteTableCatalog is a special-purpose catalog used only for Spark rewrite (compact/maintain) procedures operating on cached table instances; it cannot enumerate namespaces or tables, so listTables always throws UnsupportedOperationException.

Source

Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/SparkRewriteTableCatalog.java:42

import org.apache.iceberg.spark.source.SparkTable;
import org.apache.spark.sql.catalyst.analysis.NoSuchTableException;
import org.apache.spark.sql.catalyst.analysis.TableAlreadyExistsException;
import org.apache.spark.sql.connector.catalog.Identifier;
import org.apache.spark.sql.connector.catalog.TableCatalog;
import org.apache.spark.sql.connector.catalog.TableChange;
import org.apache.spark.sql.connector.catalog.TableInfo;
import org.apache.spark.sql.util.CaseInsensitiveStringMap;

public class SparkRewriteTableCatalog implements TableCatalog, SupportsFunctions {

  private static final String CLASS_NAME = SparkRewriteTableCatalog.class.getName();
  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 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 {

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Do not use SparkRewriteTableCatalog for discovery; it is only valid as the catalog passed to rewrite procedures.
  2. Use the real Iceberg catalog (SparkCatalog/HadoopCatalog/HiveCatalog) for listing tables.
  3. Configure SHOW TABLES against the source catalog, not the rewrite catalog.

Example fix

// before
spark.sql("SHOW TABLES IN rewrite_catalog.db");
// after
spark.sql("SHOW TABLES IN my_catalog.db"); // real catalog, then pass rewrite_catalog to the rewrite procedure
Defensive patterns

Strategy: validation

Validate before calling

if (catalog instanceof SparkRewriteTableCatalog) {
  throw new IllegalArgumentException("Rewrite catalog cannot list tables; use the source catalog");
}

Type guard

boolean supportsListing(CatalogPlugin c) {
  return !(c instanceof SparkRewriteTableCatalog);
}

Try / catch

try {
  Identifier[] tables = catalog.listTables(ns);
} catch (UnsupportedOperationException e) {
  Identifier[] tables = realCatalog.listTables(ns); // fall back to the source catalog
}

Prevention

When it happens

Trigger: Calling SparkRewriteTableCatalog.listTables(namespace), or invoking Spark procedures (e.g. rewrite_data_files) in a context where the SQL engine asks the catalog to list tables, such as SHOW TABLES or pattern-matching identifier resolution.

Common situations: Running SHOW TABLES / SHOW NAMESPACES against the rewrite catalog; configuring the rewrite catalog as a default catalog; tooling that introspects catalogs generically.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/d0e4c5e944b431ff. Report an issue: GitHub.