apache/iceberg · error · UnsupportedOperationException

Operation updateLocation is not supported after the table…

Error message

Operation updateLocation is not supported after the table is serialized

What it means

SerializableTable is a read-only snapshot of a Table used for distributed execution (it serializes the table metadata and FileIO, but cannot commit changes back to a catalog). All mutation-producing methods like updateLocation() are overridden to throw UnsupportedOperationException with this message, because a serialized table has no live catalog connection to commit metadata updates through. If you need to mutate the table, use the original Table reference obtained from a catalog.

Solutions

  1. Use the original Table reference from the catalog (Catalog.loadTable) instead of the SerializableTable copy when calling updateLocation()
  2. Check whether the code path is running on a driver/catalog-connected node rather than on a distributed worker holding a serialized table
  3. Restructure so mutation operations run outside the serialized-table scope: collect results on workers, then apply updates via the catalog-backed Table on the driver
  4. If the framework hands you a Table, verify it is not a SerializableTable (instanceof SerializableTable) before attempting writes

Example fix

// before
Table table = SerializableTable.wrap(driverTable);
table.updateLocation().setLocation(newLoc).commit();
// after
Table table = catalog.loadTable(identifier); // live, catalog-backed table
table.updateLocation().setLocation(newLoc).commit();
Defensive patterns

Strategy: try-catch

Validate before calling

if (table instanceof org.apache.iceberg.SerializableTable) {
  throw new IllegalStateException("Use a catalog-backed Table, not a SerializableTable, for commits");
}

Type guard

function isSerializableTable(t) { return t instanceof org.apache.iceberg.SerializableTable; } // guard in Java: boolean ok = !(table instanceof SerializableTable);

Try / catch

try {
  table.updateLocation().setLocation(loc).commit();
} catch (UnsupportedOperationException e) {
  if (e.getMessage().contains("not supported after the table is serialized")) {
    table = catalog.loadTable(identifier); // re-load live table and retry
    table.updateLocation().setLocation(loc).commit();
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling table.updateLocation() on a table instance that was wrapped by SerializableTable and deserialized after shipping across a task boundary (e.g. inside a Spark/Flink executor task).

Common situations: Framework-internal misuse where a serialized table is accidentally used as if it were the driver-side table; custom sink/committer code storing a SerializableTable and later attempting to set the table location; accidentally serializing a Table with SerializableTable.wrap(table) then reusing the wrapped copy for writes.

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/81cd55001b0500d4. Report an issue: GitHub.

Appendix: source

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

  @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
  public AppendFiles newAppend() {
    throw new UnsupportedOperationException(errorMsg("newAppend"));
  }

  @Override
  public RewriteFiles newRewrite() {
    throw new UnsupportedOperationException(errorMsg("newRewrite"));
  }

  @Override
  public RewriteManifests rewriteManifests() {
    throw new UnsupportedOperationException(errorMsg("rewriteManifests"));
  }

  @Override

View on GitHub (pinned to 86d9c8fc54)