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
- Complete the transaction via the Builder/Transaction API (commitTransaction / Transaction.commit) instead of calling operations().commit directly.
- Only call operations().commit on Table objects loaded from the catalog, never on the temporary in-transaction operations.
- Catch UnsupportedOperationException in shared write helpers and route to the transactional path when detected.
- 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
- Apply changes via Transaction or Builder APIs, never operations().commit on temp ops
- Only call operations().commit on tables loaded directly from the catalog
- Design write helpers around Transaction/SnapshotProducer instead of raw TableOperations
- Detect temporary operations early (refresh() throwing) and switch to the transactional path
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
- Update type %s is not supported
- Cannot call refresh on temporary table operations
- Cannot call commit on temporary table operations
- Cannot call refresh on temporary table operations
- Cannot call commit on temporary table operations
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/264e53f0585e21c2.
Report an issue: GitHub.