apache/iceberg · error · IllegalStateException
Cannot wrap catalog that does not produce BaseTransaction
Error message
Cannot wrap catalog that does not produce BaseTransaction
What it means
For a create-or-replace request, updateTable builds a Transaction via catalog.buildTable(ident, EMPTY_SCHEMA).createOrReplaceTransaction() and needs a BaseTransaction to access underlyingOps() and apply request requirements/updates; a Transaction of another implementation cannot be wrapped, so the handler throws IllegalStateException.
Solutions
- Use a catalog implementation that returns BaseTransaction from createOrReplaceTransaction (e.g. extend BaseMetastoreCatalog)
- Avoid wrapping/decorating Transaction objects before the handler consumes them
- Align server-side Iceberg dependency versions so transaction classes are the core ones
Defensive patterns
Strategy: type-guard
Validate before calling
Transaction tx = catalog.buildTable(ident, schema).createOrReplaceTransaction();
if (!(tx instanceof BaseTransaction)) {
throw new IllegalStateException("Catalog must produce BaseTransaction: " + tx.getClass());
} Type guard
function isBaseTransaction(t) { return t instanceof org.apache.iceberg.BaseTransaction; } Try / catch
try {
resp = CatalogHandlers.updateTable(catalog, ident, request);
} catch (IllegalStateException e) {
// swap to a catalog that produces BaseTransaction
} Prevention
- Test create/replace flows with the real catalog before deploying the REST adapter
- Do not decorate Transaction instances in catalog implementations
- Align Iceberg core versions across catalog modules
When it happens
Trigger: POST /v1/{prefix}/namespaces/{ns}/tables with an UpdateTableRequest that is a create/replace, against a catalog whose createOrReplaceTransaction returns a non-BaseTransaction Transaction.
Common situations: Custom Catalog implementations behind the REST adapter; catalogs that return decorated transactions; mismatched Iceberg versions where transaction types differ.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Cannot assume role to sign REST requests because is not…
- Cannot build StorageCredential, some of required attributes…
- Cannot call refresh on temporary table operations
- Cannot call refresh on temporary table operations
- Cannot commit because its Glue table already exists when…
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/ed42e25bf41c03d7.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/apache/iceberg/rest/CatalogHandlers.java:548
// metadata tables are loaded on the client side, return NoSuchTableException for now
throw new NoSuchTableException("Table does not exist: %s", ident);
}
throw new IllegalStateException("Cannot wrap catalog that does not produce BaseTable");
}
public static LoadTableResponse updateTable(
Catalog catalog, TableIdentifier ident, UpdateTableRequest request) {
TableMetadata finalMetadata;
if (isCreate(request)) {
// this is a hacky way to get TableOperations for an uncommitted table
Transaction transaction =
catalog.buildTable(ident, EMPTY_SCHEMA).createOrReplaceTransaction();
if (transaction instanceof BaseTransaction) {
BaseTransaction baseTransaction = (BaseTransaction) transaction;
finalMetadata = create(baseTransaction.underlyingOps(), request);
} else {
throw new IllegalStateException(
"Cannot wrap catalog that does not produce BaseTransaction");
}
} else {
Table table = catalog.loadTable(ident);
if (table instanceof BaseTable) {
TableOperations ops = ((BaseTable) table).operations();
finalMetadata = commit(ops, request);
} else {
throw new IllegalStateException("Cannot wrap catalog that does not produce BaseTable");
}
}
return LoadTableResponse.builder().withTableMetadata(finalMetadata).build();
}
public static void renameTable(Catalog catalog, RenameTableRequest request) {
catalog.renameTable(request.source(), request.destination());View on GitHub (pinned to 86d9c8fc54)