apache/iceberg · error · UnsupportedOperationException

does not support table invalidation

Error message

 does not support table invalidation

What it means

Capability guard in SparkCachedTableCatalog.invalidateTable (v4.0): cached table handles are looked up fresh from the underlying catalog each time, so there is nothing to invalidate and the operation is refused with the catalog class name in the message.

Source

Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/SparkCachedTableCatalog.java:91

    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);
    Preconditions.checkArgument(
        table.snapshotId() == null, "Cannot time travel based on both table identifier and AS OF");
    // Spark passes microseconds but Iceberg uses milliseconds for snapshots
    long timestampMillis = TimeUnit.MICROSECONDS.toMillis(timestampMicros);
    long snapshotId = SnapshotUtil.snapshotIdAsOfTime(table.table(), timestampMillis);
    return table.copyWithSnapshotId(snapshotId);
  }

  @Override
  public void invalidateTable(Identifier ident) {
    throw new UnsupportedOperationException(CLASS_NAME + " does not support table invalidation");
  }

  @Override
  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");
  }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Route table access through the regular Iceberg SparkCatalog, which supports invalidation
  2. Remove the cached entry via SparkTableCache management rather than invalidating through this catalog
  3. Avoid DDL/write workflows that trigger cache invalidation on tables exposed by this catalog
Defensive patterns

Strategy: try-catch

Try / catch

try { catalog.invalidateTable(ident); } catch (UnsupportedOperationException e) { /* rely on SparkTableCache lifecycle */ }

Prevention

When it happens

Trigger: Spark calling catalog.invalidateTable(ident) after writes/DDL, e.g. when executing INSERT/REFRESH flows against a table resolved via the cached-table catalog.

Common situations: Mixed-use SQL where Spark internally invalidates metadata caches between statements against tables bound to this catalog.

Related errors


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