apache/iceberg · error · ViewAlreadyExistsException
ViewAlreadyExistsException(ident)
Error message
ViewAlreadyExistsException(ident)
What it means
When createView's underlying ViewBuilder .create() fails with Iceberg's AlreadyExistsException, it is converted to Spark's ViewAlreadyExistsException for the identifier. The view with that exact name already exists in the catalog and plain CREATE VIEW refuses to overwrite it.
Source
Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/SparkCatalog.java:640
.putAll(Spark3Util.rebuildCreateProperties(properties))
.put(SparkView.QUERY_COLUMN_NAMES, COMMA_JOINER.join(queryColumnNames))
.buildKeepingLast();
org.apache.iceberg.view.View view =
asViewCatalog
.buildView(buildIdentifier(ident))
.withDefaultCatalog(currentCatalog)
.withDefaultNamespace(Namespace.of(currentNamespace))
.withQuery("spark", sql)
.withSchema(icebergSchema)
.withLocation(properties.get("location"))
.withProperties(props)
.create();
return new SparkView(catalogName, view);
} catch (org.apache.iceberg.exceptions.NoSuchNamespaceException e) {
throw new NoSuchNamespaceException(currentNamespace);
} catch (AlreadyExistsException e) {
throw new ViewAlreadyExistsException(ident);
}
}
throw new UnsupportedOperationException(
"Creating a view is not supported by catalog: " + catalogName);
}
@Override
public View replaceView(
Identifier ident,
String sql,
String currentCatalog,
String[] currentNamespace,
StructType schema,
String[] queryColumnNames,
String[] columnAliases,
String[] columnComments,
Map<String, String> properties)View on GitHub (pinned to 86d9c8fc54)
Solutions
- Use CREATE VIEW IF NOT EXISTS (or CREATE OR REPLACE VIEW) to make the statement idempotent
- Drop the existing view first if replacement is intended: DROP VIEW catalog.db.name then recreate
- Pick a different view name if the existing object is intentional
- Handle ViewAlreadyExistsException in code and treat it as success when creation is best-effort
Example fix
// before CREATE VIEW prod.analytics.daily_summary AS SELECT ...; // after CREATE VIEW IF NOT EXISTS prod.analytics.daily_summary AS SELECT ...; // or: CREATE OR REPLACE VIEW prod.analytics.daily_summary AS SELECT ...;
Defensive patterns
Strategy: validation
Validate before calling
boolean exists = spark.sql("SHOW VIEWS IN " + db).collectAsList().stream()
.anyMatch(r -> r.getString(0).equalsIgnoreCase(name));
// choose IF NOT EXISTS vs CREATE OR REPLACE based on `exists` and intent Try / catch
try {
spark.sql("CREATE VIEW " + ident + " AS SELECT ...;");
} catch (org.apache.spark.sql.catalyst.analysis.ViewAlreadyExistsException e) {
spark.sql("CREATE OR REPLACE VIEW " + ident + " AS SELECT ...;");
} Prevention
- Use CREATE VIEW IF NOT EXISTS or CREATE OR REPLACE VIEW in re-runnable scripts
- Version your view DDL so repeated deployments are idempotent
- Avoid duplicate CREATE VIEW in concurrently running jobs (serialize or lock)
- Remember tables and views are separate catalogs entries — check both with SHOW TABLES/SHOW VIEWS
When it happens
Trigger: CREATE VIEW catalog.db.name executed when a view (and in most catalogs also a table) with that identifier already exists; concurrent pipelines both attempting CREATE VIEW for the same name.
Common situations: Re-running non-idempotent migration/ETL scripts that create views; two jobs racing to create the same view; confusion between tables and views sharing the same name in the catalog; forgetting IF NOT EXISTS in DDL.
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: ${toIdentifier}
- View with same name already exists: %s
- Table with same name already exists: %s
- View with same name already exists: %s
- View already exists: toIdentifier
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/1426337ee821ce5d.
Report an issue: GitHub.