apache/iceberg · error · UnsupportedOperationException

does not support altering tables

Error message

 does not support altering tables

What it means

Capability guard in SparkCachedTableCatalog.alterTable (v4.0): the cached-table catalog is read-only over its loads, so ALTER TABLE routed here always fails; the alteration must target the underlying catalog.

Source

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

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

  @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

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Execute ALTER TABLE against the real Iceberg catalog that owns the table
  2. Fully qualify the table with the real catalog name in SQL
  3. After altering in the real catalog, refresh/re-cache the table in SparkTableCache if needed

Example fix

// before
ALTER TABLE cached_catalog.db.t ADD COLUMN c INT
// after
ALTER TABLE iceberg_catalog.db.t ADD COLUMN c INT
Defensive patterns

Strategy: validation

Validate before calling

if (catalog instanceof SparkCachedTableCatalog) {
  throw new IllegalArgumentException("ALTER TABLE not supported on cached catalog; use owning catalog");
}

Try / catch

try { catalog.alterTable(ident, changes); } catch (UnsupportedOperationException e) { realCatalog.alterTable(ident, changes); }

Prevention

When it happens

Trigger: Running ALTER TABLE statements (add column, set properties, etc.) on a table identifier resolved through the cached-table catalog.

Common situations: Users assuming the cached catalog is a full catalog; session catalog misconfiguration so ALTERs are routed to it.

Related errors


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