apache/iceberg · error · UnsupportedOperationException

Operation updateSpec is not supported after the table is…

Error message

Operation updateSpec is not supported after the table is serialized

What it means

SerializableTable guard: the table was serialized to a remote engine and this handle carries only read state, so updateSpec() (partition-spec evolution) is refused. Mutating operations must go through the original Table obtained from the catalog in the driver, not the deserialized copy.

Solutions

  1. Perform the partition evolution on the driver with a live catalog table
  2. Pass a reference to the Catalog and identifier instead of the serialized table
  3. Restrict SerializableTable usage to read paths (scans, reads)
Defensive patterns

Strategy: validation

Validate before calling

if (table instanceof SerializableTable) { throw new UnsupportedOperationException("Spec updates require a live catalog table"); }

Type guard

boolean canWrite = !(table instanceof SerializableTable);

Try / catch

try { table.updateSpec().commit(); } catch (UnsupportedOperationException e) { catalog.loadTable(id).updateSpec().commit(); }

Prevention

When it happens

Trigger: Calling updateSpec() on a SerializableTable instance, e.g., in distributed task code or after wrapping with SerializableTable.of().

Common situations: Job code that evolves partitioning mid-pipeline using a table handle that was serialized for executors.

Related errors


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

Appendix: source

Thrown at core/src/main/java/org/apache/iceberg/SerializableTable.java:357

  @Override
  public Iterable<Snapshot> snapshots() {
    return lazyTable().snapshots();
  }

  @Override
  public List<HistoryEntry> history() {
    return lazyTable().history();
  }

  @Override
  public UpdateSchema updateSchema() {
    throw new UnsupportedOperationException(errorMsg("updateSchema"));
  }

  @Override
  public UpdatePartitionSpec updateSpec() {
    throw new UnsupportedOperationException(errorMsg("updateSpec"));
  }

  @Override
  public UpdateProperties updateProperties() {
    throw new UnsupportedOperationException(errorMsg("updateProperties"));
  }

  @Override
  public ReplaceSortOrder replaceSortOrder() {
    throw new UnsupportedOperationException(errorMsg("replaceSortOrder"));
  }

  @Override
  public UpdateLocation updateLocation() {
    throw new UnsupportedOperationException(errorMsg("updateLocation"));
  }

  @Override

View on GitHub (pinned to 86d9c8fc54)