apache/iceberg · error · UnsupportedOperationException
Cannot create transactions for a %s table
Error message
Cannot create transactions for a %s table
What it means
Read-only table guard in BaseReadOnlyTable: newTransaction() would open a multi-operation transaction against the table, which read-only table wrappers do not permit. It fires on the call itself; the 'descriptor' in the message identifies which kind of read-only view rejected it.
Source
Thrown at core/src/main/java/org/apache/iceberg/BaseReadOnlyTable.java:123
throw new UnsupportedOperationException(
"Cannot update partition statistics of a " + descriptor + " table");
}
@Override
public ExpireSnapshots expireSnapshots() {
throw new UnsupportedOperationException(
"Cannot expire snapshots from a " + descriptor + " table");
}
@Override
public ManageSnapshots manageSnapshots() {
throw new UnsupportedOperationException(
"Cannot manage snapshots in a " + descriptor + " table");
}
@Override
public Transaction newTransaction() {
throw new UnsupportedOperationException(
"Cannot create transactions for a " + descriptor + " table");
}
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Obtain a writable table handle with catalog.loadTable(identifier) before newTransaction().
- Restrict read-only handles to scan/plan code paths.
- Add an instanceof/capability check in shared write utilities.
Example fix
// before Transaction tx = readOnlyTable.newTransaction(); // after Table table = catalog.loadTable(tableIdentifier); Transaction tx = table.newTransaction();
Defensive patterns
Strategy: validation
Validate before calling
if (!(table instanceof BaseReadOnlyTable)) {
Transaction tx = table.newTransaction();
} Type guard
boolean supportsTransactions(Table t) { return !(t instanceof BaseReadOnlyTable); } Try / catch
try { Transaction tx = table.newTransaction(); } catch (UnsupportedOperationException e) { table = catalog.loadTable(ident); } Prevention
- Start transactions only from catalog-loaded tables
- Type-check handles in generic write utilities
When it happens
Trigger: Calling table.newTransaction() on any BaseReadOnlyTable-backed instance (snapshot wrapper, metadata table).
Common situations: Generic ETL code starting a transaction against whichever Table object it was handed, including snapshot handles used for time-travel reads.
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
- Updating statistics is not supported by + getClass().getName
- Updating partition statistics is not supported by + getClass
- Managing snapshots is not supported by + getClass().getName(
- Cannot call refresh on temporary table operations
- Cannot update the schema of a %s table
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/a215b1f74e473998.
Report an issue: GitHub.