apache/iceberg · error · CommitFailedException

The view %s.%s has been modified concurrently

Error message

The view %s.%s has been modified concurrently

What it means

HiveViewOperations.doCommit detected that the Hive metastore view's metadata_location parameter was changed by another writer between read and commit. Iceberg re-checks the metadata location on commit to enforce compare-and-swap semantics; a mismatch means a concurrent commit succeeded first. The current commit is rejected and should be retried by the caller.

Source

Thrown at hive-metastore/src/main/java/org/apache/iceberg/hive/HiveViewOperations.java:218

                + "iceberg.hive.lock-heartbeat-interval-ms.",
            le);
      } catch (org.apache.hadoop.hive.metastore.api.AlreadyExistsException e) {
        throw new AlreadyExistsException(e, "View already exists: %s.%s", database, viewName);

      } catch (InvalidObjectException e) {
        throw new ValidationException(e, "Invalid Hive object for %s.%s", database, viewName);

      } catch (CommitFailedException | CommitStateUnknownException e) {
        throw e;

      } catch (Throwable e) {
        if (e.getMessage() != null
            && e.getMessage()
                .contains(
                    "The table has been modified. The parameter value for key '"
                        + BaseMetastoreTableOperations.METADATA_LOCATION_PROP
                        + "' is")) {
          throw new CommitFailedException(
              e, "The view %s.%s has been modified concurrently", database, viewName);
        }

        if (e.getMessage() != null
            && e.getMessage().contains("Table/View 'HIVE_LOCKS' does not exist")) {
          throw new RuntimeException(
              "Failed to acquire locks from metastore because the underlying metastore "
                  + "view '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);
        }

        LOG.error(
            "Cannot tell if commit to {}.{} succeeded, attempting to reconnect and check.",
            database,
            viewName,
            e);
        commitStatus = BaseMetastoreOperations.CommitStatus.UNKNOWN;

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Refresh the view and re-apply the operation; the commit is safe to retry after rebase.
  2. Ensure only one writer commits at a time or serialize writes through a job scheduler.
  3. Verify no external tooling (e.g. manual ALTER VIEW or metastore edits) changes metadata_location outside Iceberg.

Example fix

// before
view.refresh();
sql("CREATE OR REPLACE VIEW ...") run concurrently by two jobs

// after
retryLoop:
  try {
    view.refresh(); // pick up latest version
    view.updateSQL().set("SELECT * FROM t WHERE day < '2026-01-01'").commit();
    break retryLoop;
  } catch (CommitFailedException e) {
    // backoff and retry with fresh metadata
  }
Defensive patterns

Strategy: retry

Validate before calling

// before committing, confirm metadata hasn't moved underneath you
String current = (String) catalog.loadView(ident).properties()
    .get(BaseMetastoreTableOperations.METADATA_LOCATION_PROP);
if (!expectedMetadataLocation.equals(current)) {
  view.refresh(); // pick up concurrent commit before re-trying
}

Try / catch

try {
  view.updateSQL()...commit();
} catch (CommitFailedException e) {
  view.refresh();
  // re-apply changes and retry with backoff
}

Prevention

When it happens

Trigger: Calling a commit (e.g. table/view refresh that appends or alters the view) while another process commits to the same view; the underlying TException message contains "The table has been modified. The parameter value for key 'metadata_location' is ...".

Common situations: Two Spark/Flink jobs or engines writing the same Iceberg view simultaneously; a manually altered or restored Hive view; stale client cache reading an old metadata location.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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