apache/iceberg · error · UnsupportedOperationException
Not implemented: doCommit
Error message
Not implemented: doCommit
What it means
BaseMetastoreTableOperations.doCommit(base, metadata) is the abstract hook subclasses implement to write metadata to their metastore. The base class throws UnsupportedOperationException, so committing through an operations instance that lacks a doCommit override always fails. Like doRefresh, this flags an incomplete custom catalog implementation.
Solutions
- Override doCommit(base, metadata) in the subclass to persist the new metadata file and update the metastore pointer
- Persist a new metadata file via writeNewMetadata(metadata, overwrite) then update the metastore location atomically
- Point the catalog at a complete TableOperations implementation
Example fix
// before
class MyTableOperations extends BaseMetastoreTableOperations { }
// after
class MyTableOperations extends BaseMetastoreTableOperations {
@Override
protected void doCommit(TableMetadata base, TableMetadata metadata) {
String newLocation = writeNewMetadata(metadata, version >= 0 /* overwrite */);
updateMetastoreTable(metadataLocation(), newLocation);
}
} Defensive patterns
Strategy: type-guard
Validate before calling
if (ops.getClass().getMethod("doCommit", TableMetadata.class, TableMetadata.class).getDeclaringClass() == BaseMetastoreTableOperations.class) { throw new IllegalStateException("Custom ops must override doCommit"); } Type guard
static boolean supportsCommit(TableOperations ops) { return !(ops instanceof BaseMetastoreTableOperations) || !ops.getClass().getName().equals(BaseMetastoreTableOperations.class.getName()); } Try / catch
try { ops.commit(base, metadata); }
catch (UnsupportedOperationException e) { /* doCommit not implemented; complete the custom implementation */ } Prevention
- Always override doCommit when extending BaseMetastoreTableOperations
- Test commit paths against a real metastore backend
- Use writeNewMetadata + atomic metastore update in the override
When it happens
Trigger: Calling commit(base, metadata) (including the early no-op guard passing) on a subclass that does not override doCommit; requestRefresh/commit flows in a half-implemented custom catalog.
Common situations: Custom Hive/Nessie/Glue-style catalogs missing the doCommit override; test stubs of BaseMetastoreTableOperations used in production paths; incomplete migration to a newer base-class API.
Related errors
- Not implemented: doRefresh
- doesn't implement setPageSource(PageReadStore)
- Altering a view is not supported by catalog:
- Altering a view is not supported by catalog
- Altering a view is not supported by catalog
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/76491e39793c15e3.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/apache/iceberg/BaseMetastoreTableOperations.java:138
// if the metadata is not changed, return early
if (base == metadata) {
LOG.info("Nothing to commit.");
return;
}
long start = System.currentTimeMillis();
doCommit(base, metadata);
CatalogUtil.deleteRemovedMetadataFiles(io(), base, metadata);
requestRefresh();
LOG.info(
"Successfully committed to table {} in {} ms",
tableName(),
System.currentTimeMillis() - start);
}
protected void doCommit(TableMetadata base, TableMetadata metadata) {
throw new UnsupportedOperationException("Not implemented: doCommit");
}
protected void requestRefresh() {
this.shouldRefresh = true;
}
protected void disableRefresh() {
this.shouldRefresh = false;
}
protected String writeNewMetadataIfRequired(boolean newTable, TableMetadata metadata) {
return newTable && metadata.metadataFileLocation() != null
? metadata.metadataFileLocation()
: writeNewMetadata(metadata, currentVersion() + 1);
}
protected String writeNewMetadata(TableMetadata metadata, int newVersion) {
String newTableMetadataFilePath = newTableMetadataFilePath(metadata, newVersion);View on GitHub (pinned to 86d9c8fc54)