{"record":{"id":"3c1e6147d7f0bef2","repo":"apache/iceberg","slug":"operation-newtransaction-is-not-supported-after-th","errorCode":null,"errorMessage":"Operation newTransaction is not supported after the table is serialized","messagePattern":"Operation newTransaction is not supported after the table is serialized","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/SerializableTable.java","lineNumber":432,"sourceCode":"\n  @Override\n  public UpdatePartitionStatistics updatePartitionStatistics() {\n    throw new UnsupportedOperationException(errorMsg(\"updatePartitionStatistics\"));\n  }\n\n  @Override\n  public ExpireSnapshots expireSnapshots() {\n    throw new UnsupportedOperationException(errorMsg(\"expireSnapshots\"));\n  }\n\n  @Override\n  public ManageSnapshots manageSnapshots() {\n    throw new UnsupportedOperationException(errorMsg(\"manageSnapshots\"));\n  }\n\n  @Override\n  public Transaction newTransaction() {\n    throw new UnsupportedOperationException(errorMsg(\"newTransaction\"));\n  }\n\n  @Override\n  public StaticTableOperations operations() {\n    return (StaticTableOperations) ((BaseTable) lazyTable()).operations();\n  }\n\n  private String errorMsg(String operation) {\n    return String.format(\"Operation %s is not supported after the table is serialized\", operation);\n  }\n\n  public static class SerializableMetadataTable extends SerializableTable {\n    private final MetadataTableType type;\n    private final String baseTableName;\n\n    protected SerializableMetadataTable(BaseMetadataTable metadataTable) {\n      super(metadataTable);\n      this.type = metadataTable.metadataTableType();","sourceCodeStart":414,"sourceCodeEnd":450,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/SerializableTable.java#L414-L450","documentation":"SerializableTable is an immutable, read-only snapshot of table state sent to other cluster nodes; it cannot support transactions, since a Transaction requires committing metadata updates through a live TableOperations. Calling newTransaction() therefore always throws this UnsupportedOperationException. Transactions must be opened on a table loaded from its catalog.","triggerScenarios":"Calling table.newTransaction() on a Table instance that is a SerializableTable — e.g. inside a serialized task closure, a broadcast variable, or a table produced by SerializableTable.copyOf().","commonSituations":"Trying to group multiple writes/updates transactionally from within a Spark/Flink executor task where only the serialized table is available; custom integrations that pass tables across process boundaries and then attempt writes.","solutions":["Reload the table via catalog.loadTable(location) on the node where the transaction should run, then call newTransaction() on that instance.","Restructure so transactions are opened in the driver (where the catalog-backed Table lives) and only scan/read work is distributed using SerializableTable.","Check instanceof SerializableTable (or !table operations support) before attempting transactional code and fail with an actionable message."],"exampleFix":"// before\nTransaction tx = serializedTable.newTransaction(); // throws\n\n// after\nTable table = catalog.loadTable(tableLocation);\nTransaction tx = table.newTransaction();","handlingStrategy":"type-guard","validationCode":"if (table instanceof org.apache.iceberg.SerializableTable) {\n  table = catalog.loadTable(table.location()); // reload before opening a transaction\n}","typeGuard":"boolean supportsTransactions(Table t) {\n  return !(t instanceof org.apache.iceberg.SerializableTable);\n}","tryCatchPattern":"try {\n  Transaction tx = table.newTransaction();\n  // ...\n  tx.commitTransaction();\n} catch (UnsupportedOperationException e) {\n  throw new IllegalStateException(\"Open transactions on a catalog-loaded table, not a serialized one\", e);\n}","preventionTips":["Never distribute tables intended for writes; distribute only the location string and reload per node.","Group multi-step writes in the driver via catalog.loadTable(...).newTransaction().","When writing library code, take a Catalog parameter for write paths instead of a bare Table."],"tags":["java","unsupported-operation","serialization","transaction"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}