apache/iceberg · error · AlreadyExistsException

View with same name already exists: %s

Error message

View with same name already exists: %s

What it means

In JdbcCatalog's view builder transaction wrapper, replaceTransaction() under SchemaVersion.V1 first checks viewExists(identifier); if a view with the same name exists it throws AlreadyExistsException "View with same name already exists: %s". In V1 schema, tables and views share a namespace, so replacing a table via transaction is blocked when a view occupies the name.

Source

Thrown at core/src/main/java/org/apache/iceberg/jdbc/JdbcCatalog.java:921

  }

  /**
   * The purpose of this class is to add view detection only when SchemaVersion.V1 schema is used
   * when replacing a table.
   */
  protected class ViewAwareTableBuilder extends BaseMetastoreCatalogTableBuilder {

    private final TableIdentifier identifier;

    public ViewAwareTableBuilder(TableIdentifier identifier, Schema schema) {
      super(identifier, schema);
      this.identifier = identifier;
    }

    @Override
    public Transaction replaceTransaction() {
      if (schemaVersion == JdbcUtil.SchemaVersion.V1 && viewExists(identifier)) {
        throw new AlreadyExistsException("View with same name already exists: %s", identifier);
      }

      return super.replaceTransaction();
    }
  }
}

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Drop the conflicting view first with catalog.dropView(identifier), then perform the replace
  2. Choose a different name for the new table/view
  3. Upgrade the JDBC catalog schema version (V1 -> V0/V1 handling differs; use a schema where views are stored separately) if name sharing is required
  4. Check viewExists(identifier) before starting a replace transaction

Example fix

// before
Transaction t = catalog.buildTable(ident, schema).replaceTransaction();
// after
if (catalog.viewExists(ident)) {
  catalog.dropView(ident);
}
Transaction t = catalog.buildTable(ident, schema).replaceTransaction();
Defensive patterns

Strategy: validation

Validate before calling

if (catalog.viewExists(ident)) {
  throw new IllegalStateException("Name occupied by a view: " + ident);
}
Transaction t = catalog.buildTable(ident, schema).replaceTransaction();

Try / catch

try {
  Transaction t = catalog.buildTable(ident, schema).replaceTransaction();
} catch (AlreadyExistsException e) {
  // a view occupies this name: drop it or pick a new name
  throw e;
}

Prevention

When it happens

Trigger: Calling transaction.replaceTransaction() on a JdbcCatalog view builder (e.g., via replaceTransaction on a View or table builder transaction) where an entity with the same identifier already exists as a view and schemaVersion is V1.

Common situations: Creating/replacing a table with the same name as an existing view; name reuse after a table was dropped but a view was created with the same name; upgrading from setups that allowed shared names.

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/1edf77f1c093b24b. Report an issue: GitHub.