apache/iceberg · error · CommitFailedException

The table %s.%s has been modified concurrently

Error message

The table %s.%s has been modified concurrently

What it means

HMS reported the table was already modified (e.g. InvalidOperationException from a failed alter), and before declaring failure doCommit re-checks the commit status in strict mode by comparing the stored metadata_location with the new one. If the check confirms the location does not match this commit, a CommitFailedException 'modified concurrently' is thrown — the commit did not land because another writer changed the table first.

Source

Thrown at hive-metastore/src/main/java/org/apache/iceberg/hive/HiveTableOperations.java:393

                  + "table 'HIVE_LOCKS' does not exist. This can occur when using an embedded metastore which does not "
                  + "support transactions. To fix this use an alternative metastore.",
              e);
        }

        commitStatus = BaseMetastoreOperations.CommitStatus.UNKNOWN;
        if (e.getMessage() != null
            && e.getMessage()
                .contains(
                    "The table has been modified. The parameter value for key '"
                        + HiveTableOperations.METADATA_LOCATION_PROP
                        + "' is")) {
          // It's possible the HMS client incorrectly retries a successful operation, due to network
          // issue for example, and triggers this exception. So we need double-check to make sure
          // this is really a concurrent modification. Hitting this exception means no pending
          // requests, if any, can succeed later, so it's safe to check status in strict mode
          commitStatus = checkCommitStatusStrict(newMetadataLocation, tableMetadata);
          if (commitStatus == BaseMetastoreOperations.CommitStatus.FAILURE) {
            throw new CommitFailedException(
                e, "The table %s.%s has been modified concurrently", database, tableName);
          }
        } else {
          LOG.error(
              "Cannot tell if commit to {}.{} succeeded, attempting to reconnect and check.",
              database,
              tableName,
              e);
          commitStatus = checkCommitStatus(newMetadataLocation, tableMetadata);
        }

        switch (commitStatus) {
          case SUCCESS:
            break;
          case FAILURE:
            throw e;
          case UNKNOWN:
            throw new CommitStateUnknownException(e);

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Retry the whole operation with refreshed table metadata (CommitFailedException is retriable)
  2. Enable Hive lock acquisition so concurrent committers are serialized
  3. Inspect table history/metadata_location to identify the competing writer
  4. Move to a catalog with stronger commit semantics if contention is frequent

Example fix

// before
 table.newOverwrite().deleteFile(f).commit(); // may fail under concurrency
// after
RetryUtil.retry(CommitFailedException.class, 3, () -> {
  table.refresh();
  table.newOverwrite().deleteFile(f).commit();
});
Defensive patterns

Strategy: retry

Validate before calling

String loc = hmsClient.getTable(db, tbl).getParameters().get("metadata_location");
if (!Objects.equals(loc, expectedBaseLocation)) table.refresh();

Try / catch

try {
  table.newAppend().appendFile(f).commit();
} catch (CommitFailedException e) {
  table.refresh();
  // retry with backoff, bounded attempts
}

Prevention

When it happens

Trigger: doCommit's persistTable throws an exception interpreted as concurrent modification (already-moved metadata_location); the subsequent checkCommitStatusStrict finds metadata_location != newMetadataLocation and status FAILURE.

Common situations: Concurrent Iceberg committers via HiveCatalog without sufficient locking; HMS client retry of a successful alter masking real concurrency; two engines (Spark + Flink) writing the same table.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/72c037d0cfc3f9bb. Report an issue: GitHub.