apache/iceberg · error · UnsupportedOperationException
Operation updateSpec is not supported after the table is ser
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.
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"));
}
@OverrideView on GitHub (pinned to 86d9c8fc54)
Solutions
- Perform the partition evolution on the driver with a live catalog table
- Pass a reference to the Catalog and identifier instead of the serialized table
- 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
- Keep partition evolution on the driver
- Never serialize tables intended for write operations
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
- Operation updateSchema is not supported after the table is s
- Operation updateProperties is not supported after the table
- Operation replaceSortOrder is not supported after the table
- does not have a metadata file location
- Cannot load metadata: metadata file location is null
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/48ed2e6203c29c3a.
Report an issue: GitHub.