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

  1. Drop the existing table at that identifier before creating the view
  2. Use a different identifier for the view
  3. Check catalog.tableExists(ident) first and branch your DDL logic
  4. 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

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


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/4b9e6dd578264af8. Report an issue: GitHub.