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

  1. Override doCommit(base, metadata) in the subclass to persist the new metadata file and update the metastore pointer
  2. Persist a new metadata file via writeNewMetadata(metadata, overwrite) then update the metastore location atomically
  3. 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

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


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)