apache/iceberg · error · java.lang.UnsupportedOperationException

SparkCachedTableCatalog does not support purging tables

Error message

SparkCachedTableCatalog does not support purging tables

What it means

SparkCachedTableCatalog.purgeTable() throws UnsupportedOperationException always. Purging deletes table data and metadata permanently; a cache-backed, read-only view of tables can never perform this, so the method is a hard stop.

Source

Thrown at spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/SparkCachedTableCatalog.java:113

  public SparkTable createTable(
      Identifier ident, StructType schema, Transform[] partitions, Map<String, String> properties)
      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");
  }

  @Override
  public boolean purgeTable(Identifier ident) throws UnsupportedOperationException {
    throw new UnsupportedOperationException(CLASS_NAME + " does not support purging tables");
  }

  @Override
  public void renameTable(Identifier oldIdent, Identifier newIdent) {
    throw new UnsupportedOperationException(CLASS_NAME + " does not support renaming tables");
  }

  @Override
  public void initialize(String catalogName, CaseInsensitiveStringMap options) {
    this.name = catalogName;
  }

  @Override
  public String name() {
    return name;
  }

  private SparkTable load(Identifier ident) throws NoSuchTableException {

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Purge via the owning catalog: ExpireSnapshots on the real org.apache.iceberg.Table, or PURGE TABLE against the original catalog identifier.
  2. Run the purge from a session where the table identifier resolves to SparkCatalog (not the cached catalog).
  3. If data deletion is the goal, use table.io().deleteFile / deleteFiles through the underlying Table rather than the catalog API.

Example fix

// before
cachedCatalog.purgeTable(Identifier.of(new String[]{"db"}, "t"));

// after
Table table = catalogOps.loadTable("db.t"); // real catalog
table.expireSnapshots().expireOlderThan(System.currentTimeMillis() - retentionMs).commit();
Defensive patterns

Strategy: validation

Validate before calling

if (catalog instanceof SparkCachedTableCatalog) {
  throw new IllegalArgumentException("purgeTable is not supported on SparkCachedTableCatalog; use ExpireSnapshots on the real table");
}

Type guard

boolean canPurge = !(catalog instanceof SparkCachedTableCatalog);

Try / catch

try {
  catalog.purgeTable(ident);
} catch (UnsupportedOperationException e) {
  // purge via real catalog or table.expireSnapshots()
}

Prevention

When it happens

Trigger: Calling SparkCachedTableCatalog.purgeTable(ident) directly, or running PURGE TABLE / DROP TABLE PURGE in Spark SQL where resolution lands on the cached catalog.

Common situations: Retention/cleanup jobs that purge expired tables but route through the cached catalog; users attempting to reclaim storage after a cached read session; generic tooling that calls purgeTable on any CatalogPlugin.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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