apache/iceberg · error · AlreadyExistsException

Cannot create or replace table

Error message

Cannot create or replace table %s: a view with the same name already exists

What it means

When staging a create-or-replace, SparkSessionCatalog checks whether a view occupies the target identifier; if so it throws AlreadyExistsException. This explicit guard is needed because StagingTableCatalog's stageCreateOrReplace contract does not declare a checked collision exception, so the conflict must be surfaced eagerly.

Solutions

  1. Drop the conflicting view first (DROP VIEW ident) then retry the create-or-replace
  2. Choose a different table name if the view is still needed
  3. Move views and tables into separate namespaces to avoid identifier collisions

Example fix

-- before
CREATE OR REPLACE TABLE prod.db.report (...)
-- after
DROP VIEW prod.db.report;
CREATE OR REPLACE TABLE prod.db.report (...)
Defensive patterns

Strategy: validation

Validate before calling

// ensure no view occupies the identifier before create-or-replace
if (catalog.viewExists(ident)) {
  spark.sql("DROP VIEW " + ident);
}

Try / catch

try {
  spark.sql("CREATE OR REPLACE TABLE " + ident + " (...)");
} catch (AlreadyExistsException e) {
  // a view with the same name exists; resolve manually
  throw e;
}

Prevention

When it happens

Trigger: Executing CREATE OR REPLACE TABLE ident when a view named ident already exists in either the Iceberg view catalog or the delegated session catalog; viewExists(ident) returns true during stageCreateOrReplace.

Common situations: Namespace shared between views and tables where a view was created earlier; migration from a view to a table; scripts assuming table-only 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/e765c008da22e48a. Report an issue: GitHub.

Appendix: source

Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/SparkSessionCatalog.java:316

    try {
      // create the table with the session catalog, then wrap it in a staged table that will delete
      // to roll back
      Table table = catalog.createTable(ident, schema, partitions, properties);
      return new RollbackStagedTable(catalog, ident, table);

    } catch (TableAlreadyExistsException e) {
      // the table was deleted, but now already exists again. retry the replace.
      return stageReplace(ident, schema, partitions, properties);
    }
  }

  @Override
  public StagedTable stageCreateOrReplace(
      Identifier ident, StructType schema, Transform[] partitions, Map<String, String> properties)
      throws NoSuchNamespaceException {
    if (viewExists(ident)) {
      // StagingTableCatalog does not declare a checked collision exception for create-or-replace.
      throw new AlreadyExistsException(
          "Cannot create or replace table %s: a view with the same name already exists", ident);
    }

    String provider = properties.get("provider");
    TableCatalog catalog;
    if (useIceberg(provider)) {
      if (asStagingCatalog != null) {
        return asStagingCatalog.stageCreateOrReplace(ident, schema, partitions, properties);
      }
      catalog = icebergCatalog;
    } else {
      catalog = getSessionCatalog();
    }

    // drop the table if it exists
    catalog.dropTable(ident);

    try {

View on GitHub (pinned to 86d9c8fc54)