apache/iceberg · error · AlreadyExistsException
View with same name already exists: %s
Error message
View with same name already exists: %s
What it means
During a table's first commit (doCommit with base == null), InMemoryCatalog checks whether a view is already registered under the same identifier. Iceberg keeps tables and views in separate maps but shares one identifier namespace, so creating a table over an existing view name would collide; it throws AlreadyExistsException to preserve the invariant.
Source
Thrown at core/src/main/java/org/apache/iceberg/inmemory/InMemoryCatalog.java:438
} else {
refreshFromMetadataLocation(latestLocation);
}
}
@Override
public void doCommit(TableMetadata base, TableMetadata metadata) {
String newLocation = writeNewMetadataIfRequired(base == null, metadata);
String oldLocation = base == null ? null : base.metadataFileLocation();
synchronized (InMemoryCatalog.this) {
if (null == base && !namespaceExists(tableIdentifier.namespace())) {
throw new NoSuchNamespaceException(
"Cannot create table %s. Namespace does not exist: %s",
tableIdentifier, tableIdentifier.namespace());
}
if (views.containsKey(tableIdentifier)) {
throw new AlreadyExistsException(
"View with same name already exists: %s", tableIdentifier);
}
tables.compute(
tableIdentifier,
(k, existingLocation) -> {
if (!Objects.equal(existingLocation, oldLocation)) {
if (null == base) {
throw new AlreadyExistsException("Table already exists: %s", tableName());
}
if (null == existingLocation) {
throw new NoSuchTableException("Table does not exist: %s", tableName());
}
throw new CommitFailedException(
"Cannot commit to table %s metadata location from %s to %s "
+ "because it has been concurrently modified to %s",View on GitHub (pinned to 86d9c8fc54)
Solutions
- Check catalog.viewExists(ident) before createTable and drop the view if replacement is intended.
- Pick a distinct name for the table.
- Register the table in a different namespace to avoid the shared-name collision.
Example fix
// before
catalog.createTable(ident, schema);
// after
if (catalog.viewExists(ident)) {
catalog.dropView(ident); // only if replacement is intended
}
catalog.createTable(ident, schema); Defensive patterns
Strategy: validation
Validate before calling
if (catalog.viewExists(ident)) { throw new IllegalStateException("View occupies table name: " + ident); } Try / catch
try { catalog.createTable(ident, schema); } catch (AlreadyExistsException e) { // inspect whether a view holds the name and resolve } Prevention
- Reserve distinct name spaces for tables and views per namespace
- Check both tableExists and viewExists before creating either
- Document ownership of names in shared namespaces
When it happens
Trigger: catalog.createTable(ident, ...) or any initial table commit where views.containsKey(ident) is true — i.e. a view with the same fully-qualified name exists.
Common situations: Recreating a table after it was replaced by a view of the same name; name collisions between teams sharing a namespace; scripts that drop tables but the name was re-registered as a view.
Related errors
- Namespace %s is not empty. Contains %d view(s).
- Cannot list views for namespace. Namespace does not exist: %
- Cannot rename %s to %s. View does not exist
- Cannot create table %s. Namespace does not exist: %s
- Table already exists: %s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/6ecc9ec3bc0305e1.
Report an issue: GitHub.