apache/iceberg · error · ViewAlreadyExistsException
ViewAlreadyExistsException(ident)
Error message
ViewAlreadyExistsException(ident)
What it means
Before creating or renaming a view, SparkSessionCatalog calls checkTableNotExists, which throws ViewAlreadyExistsException if a table already exists at the identifier. This guard prevents view DDL from silently colliding with an existing table of the same name. It reflects Iceberg's strict namespace separation: a name can only be one thing.
Source
Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/SparkSessionCatalog.java:658
@Override
public void renameView(Identifier fromIdentifier, Identifier toIdentifier)
throws NoSuchViewException, ViewAlreadyExistsException {
checkTableNotExists(toIdentifier);
if (null != asViewCatalog && asViewCatalog.viewExists(fromIdentifier)) {
asViewCatalog.renameView(fromIdentifier, toIdentifier);
} else if (isViewCatalog()) {
getSessionCatalog().renameView(fromIdentifier, toIdentifier);
} else {
throw new UnsupportedOperationException(
"Renaming a view is not supported by catalog: " + catalogName);
}
}
private void checkTableNotExists(Identifier ident) throws ViewAlreadyExistsException {
if (tableExists(ident)) {
throw new ViewAlreadyExistsException(ident);
}
}
private void checkViewNotExists(Identifier ident) throws TableAlreadyExistsException {
if (viewExists(ident)) {
throw new TableAlreadyExistsException(ident);
}
}
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Drop the existing table at that identifier before creating the view
- Use a different identifier for the view
- Check catalog.tableExists(ident) first and branch your DDL logic
- Use CREATE OR REPLACE VIEW if you intend to replace (note this replaces views, not tables)
Example fix
// before
spark.sql("CREATE VIEW db.v AS SELECT 1"); // ViewAlreadyExistsException if db.v is a table
// after
if (!catalog.tableExists(Identifier.of(new String[]{"db"}, "v"))) {
spark.sql("CREATE VIEW db.v AS SELECT 1");
} Defensive patterns
Strategy: validation
Validate before calling
if (catalog.tableExists(ident)) {
throw new IllegalStateException("Table " + ident + " blocks view creation at this name");
} Type guard
boolean nameFreeForView = !catalog.tableExists(ident);
Try / catch
try {
catalog.createView(ident, sql, schema);
} catch (org.apache.iceberg.exceptions.ViewAlreadyExistsException e) {
// drop the conflicting table or choose a new name
} Prevention
- Check tableExists before creating views with the same name
- Use distinct naming conventions for tables vs views
- Make DDL scripts idempotent: drop-if-exists or conditional create
- Audit legacy table names before introducing views
When it happens
Trigger: CREATE VIEW db.v (or renameView landing on db.v) when a table named db.v already exists in the catalog.
Common situations: Name collisions between legacy tables and new views; re-running idempotent DDL scripts that previously created a table with the same name; migration scripts assuming views and tables share separate namespaces.
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
- TableAlreadyExistsException(ident)
- e (wrapped NoSuchNamespaceException)
- NoSuchViewException(ident)
- Creating a view is not supported by catalog: ${catalogName}
- Replacing a view is not supported by catalog: ${catalogName}
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/4b9e6dd578264af8.
Report an issue: GitHub.