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
- Check viewExists/load the view before creating; use CREATE OR REPLACE if overwrite is intended
- Handle AlreadyExistsException and fall back to an update path
- 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
- Load current metadata before deciding create vs replace commit
- Never retry a failed creation with a null base without checking existence
- Prefer catalog-level createOrReplace APIs over raw ops.commit
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
- View already exists: %s
- View with same name already exists: %s.%s
- %s already exists: %s.%s
- View already exists: %s.%s
- Table already exists: %s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/fa1af21ac5d5ac33.
Report an issue: GitHub.