apache/iceberg · error · AlreadyExistsException

View already exists: %s

Error message

View already exists: %s

What it means

When committing with a null base (i.e., attempting view creation), BaseViewOperations.commit checks whether the view already exists (current() != null). If so, the creation races with an existing view and throws AlreadyExistsException instead of silently overwriting.

Source

Thrown at core/src/main/java/org/apache/iceberg/view/BaseViewOperations.java:115

      currentMetadataLocation = null;
      version = -1;
      throw e;
    }

    return current();
  }

  @Override
  @SuppressWarnings("ImmutablesReferenceEquality")
  public void commit(ViewMetadata base, ViewMetadata metadata) {
    // if the metadata is already out of date, reject it
    if (base != current()) {
      if (base != null) {
        throw new CommitFailedException("Cannot commit: stale view metadata");
      } else {
        // when current is non-null, the view exists. but when base is null, the commit is trying
        // to create the view
        throw new AlreadyExistsException("View already exists: %s", viewName());
      }
    }

    // if the metadata is not changed, return early
    if (base == metadata) {
      LOG.info("Nothing to commit.");
      return;
    }

    long start = System.currentTimeMillis();
    doCommit(base, metadata);
    requestRefresh();

    LOG.info(
        "Successfully committed to view {} in {} ms",
        viewName(),
        System.currentTimeMillis() - start);
  }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Check viewExists/load the view before creating; use CREATE OR REPLACE if overwrite is intended
  2. Handle AlreadyExistsException and fall back to an update path
  3. Retry with a fresh null-base creation only after confirming the view is absent

Example fix

// before
ops.commit(null, metadata); // create
// after
if (((BaseViewOperations) ops).current() == null) {
  ops.commit(null, metadata);
} else {
  ops.commit(((BaseViewOperations) ops).current(), metadata); // replace
}
Defensive patterns

Strategy: validation

Validate before calling

boolean viewExists = ((BaseViewOperations) ops).current() != null; if (base == null && viewExists) { /* use replace, not create */ }

Try / catch

try { ops.commit(null, metadata); } catch (AlreadyExistsException e) { // view exists: load and commit replace instead }

Prevention

When it happens

Trigger: ops.commit(null, metadata) to create a view when current() is non-null — another client created the view first, or the caller mistakenly passed null base for an existing view.

Common situations: Concurrent CREATE VIEW statements targeting the same name; retry logic that re-commits with null base after the first commit actually succeeded; direct use of ViewOperations by custom catalogs.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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