apache/iceberg · error · ViewAlreadyExistsException
View already exists: ident
Error message
View already exists: ident
What it means
SparkCatalog.createView throws ViewAlreadyExistsException when the underlying Iceberg catalog already contains a view (or, depending on catalog, an entry) at the target identifier. The underlying create() raises AlreadyExistsException and it is translated to ViewAlreadyExistsException with the Spark identifier. The existing view is left untouched.
Solutions
- Use CREATE VIEW IF NOT EXISTS, or drop the existing view first: DROP VIEW <ident>.
- Check the existing view with DESCRIBE VIEW <ident> to decide whether to keep or replace it; use CREATE OR REPLACE VIEW to overwrite intentionally.
- For programmatic use, guard with asViewCatalog.viewExists(ident) before createView, or catch ViewAlreadyExistsException.
- In CI/seed scripts, make creation idempotent (IF NOT EXISTS or drop-then-create).
Example fix
-- before CREATE VIEW analytics.daily_metrics AS SELECT ...; -- fails on rerun -- after CREATE VIEW IF NOT EXISTS analytics.daily_metrics AS SELECT ...;
Defensive patterns
Strategy: try-catch
Validate before calling
if (asViewCatalog.viewExists(ident)) {
// decide: keep, replace, or skip
} Try / catch
try {
spark.sql("CREATE VIEW " + ident + " AS " + sqlText);
} catch (ViewAlreadyExistsException e) {
// treat as success for idempotent runs, or use CREATE OR REPLACE VIEW
} Prevention
- Use CREATE VIEW IF NOT EXISTS in all provisioning/seed scripts.
- Use CREATE OR REPLACE VIEW when overwriting is intended.
- Make CI view creation idempotent to survive re-runs and races.
- Remember views and tables share no name slot — check both when a name seems free.
When it happens
Trigger: Running CREATE VIEW <ident> (SparkCatalog.java:606 createView) when a view with the same identifier already exists in the catalog; re-running a provisioning/seed script without IF NOT EXISTS; a concurrent job created the same view between the existence check and the create.
Common situations: Idempotent deployment scripts re-executed; race between two Spark jobs creating the same view; developer assumes tables and views can share a name (they cannot in the same identifier space here); leftover view from a previous experiment.
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
- Altering a view is not supported by catalog: catalogName
- Cannot create table as it already exists
- Cannot rename as for backup. The backup table already…
- Cannot rename as for backup. The backup table already…
- Cannot unset reserved property
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/8f81ca6491632339.
Report an issue: GitHub.
Appendix: source
Thrown at spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/SparkCatalog.java:641
.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)