apache/iceberg · error · UnsupportedOperationException

Cannot call commit on temporary table operations

Error message

Cannot call commit on temporary table operations

What it means

An UnsupportedOperationException thrown by the temporary TableOperations wrapper's commit(base, metadata). The temporary operations object only holds uncommitted metadata for a create/replace in progress; the real commit goes through the REST commit path, so a direct commit() on the temp wrapper is forbidden by design.

Source

Thrown at core/src/main/java/org/apache/iceberg/rest/RESTTableOperations.java:349

  }

  @Override
  public TableOperations temp(TableMetadata uncommittedMetadata) {
    return new TableOperations() {
      @Override
      public TableMetadata current() {
        return uncommittedMetadata;
      }

      @Override
      public TableMetadata refresh() {
        throw new UnsupportedOperationException(
            "Cannot call refresh on temporary table operations");
      }

      @Override
      public void commit(TableMetadata base, TableMetadata metadata) {
        throw new UnsupportedOperationException("Cannot call commit on temporary table operations");
      }

      @Override
      public String metadataFileLocation(String fileName) {
        return RESTTableOperations.metadataFileLocation(uncommittedMetadata, fileName);
      }

      @Override
      public LocationProvider locationProvider() {
        return LocationProviders.locationsFor(
            uncommittedMetadata.location(), uncommittedMetadata.properties());
      }

      @Override
      public FileIO io() {
        return RESTTableOperations.this.io();
      }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Complete the transaction via the Builder/Transaction API (commitTransaction / Transaction.commit) instead of calling operations().commit directly.
  2. Only call operations().commit on Table objects loaded from the catalog, never on the temporary in-transaction operations.
  3. Catch UnsupportedOperationException in shared write helpers and route to the transactional path when detected.
  4. Refactor helpers to accept a Transaction or SnapshotProducer rather than raw TableOperations.

Example fix

// before
table.operations().commit(table.operations().current(), newMetadata); // temp ops
// after
Transaction tx = table.newTransaction();
/* apply changes */
tx.commitTransaction();
Defensive patterns

Strategy: type-guard

Type guard

boolean supportsCommit(TableOperations ops) { try { ops.commit(ops.current(), ops.current()); return true; } catch (UnsupportedOperationException e) { return false; } } // better: only commit via catalog-loaded TableOperations

Try / catch

try { ops.commit(base, metadata); } catch (UnsupportedOperationException e) { /* temporary operations: route through Transaction/Builder API */ }

Prevention

When it happens

Trigger: Calling table.operations().commit(base, metadata) — or invoking APIs that route through TableOperations.commit — on the temporary operations used during a create/replace transaction in the REST catalog.

Common situations: Generic write pipelines that call operations().commit unconditionally, including on in-transaction table objects; custom append/overwrite helpers operating on a temp table snapshot; code written for real TableOperations reused against transactional temporary ones.

Related errors


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