apache/iceberg · error · AlreadyExistsException

View with same name already exists: %s

Error message

View with same name already exists: %s

What it means

In JDBC catalog schema V1, tables and views share the same name space in the underlying jdbc_tables record store (V1 predates the separate views table). Before creating a table, createTable checks JdbcUtil.viewExists and throws AlreadyExistsException if a view of the same name is registered, preventing silent shadowing of a view by a table.

Source

Thrown at core/src/main/java/org/apache/iceberg/jdbc/JdbcTableOperations.java:176

      LOG.debug("Successfully committed to existing table: {}", tableIdentifier);
    } else {
      throw new CommitFailedException(
          "Failed to update table %s from catalog %s", tableIdentifier, catalogName);
    }
  }

  private void createTable(String newMetadataLocation) throws SQLException, InterruptedException {
    Namespace namespace = tableIdentifier.namespace();
    if (PropertyUtil.propertyAsBoolean(catalogProperties, JdbcUtil.STRICT_MODE_PROPERTY, false)
        && !JdbcUtil.namespaceExists(catalogName, connections, namespace)) {
      throw new NoSuchNamespaceException(
          "Cannot create table %s in catalog %s. Namespace %s does not exist",
          tableIdentifier, catalogName, namespace);
    }

    if (schemaVersion == JdbcUtil.SchemaVersion.V1
        && JdbcUtil.viewExists(catalogName, connections, tableIdentifier)) {
      throw new AlreadyExistsException("View with same name already exists: %s", tableIdentifier);
    }

    if (JdbcUtil.tableExists(schemaVersion, catalogName, connections, tableIdentifier)) {
      throw new AlreadyExistsException("Table already exists: %s", tableIdentifier);
    }

    int insertRecord =
        JdbcUtil.doCommitCreateTable(
            schemaVersion,
            connections,
            catalogName,
            namespace,
            tableIdentifier,
            newMetadataLocation);

    if (insertRecord == 1) {
      LOG.debug("Successfully committed to new table: {}", tableIdentifier);
    } else {

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Choose a different name for the new table, or drop the existing view (catalog.dropView) if it is no longer needed
  2. Upgrade the JDBC catalog schema to V1 with separate view handling and confirm which entity owns the name: catalog.tableExists vs catalog.viewExists
  3. List views in the namespace (catalog.listViews) to see the conflicting registration

Example fix

// before
if (catalog.viewExists(ident)) { throw ...; }
catalog.createTable(ident, schema);
// after
if (catalog.viewExists(ident)) {
  catalog.dropView(ident); // deliberate replacement
}
catalog.createTable(ident, schema);
Defensive patterns

Strategy: validation

Validate before calling

if (catalog.viewExists(identifier)) { throw new IllegalStateException("Name taken by view: " + identifier); }

Try / catch

try { catalog.createTable(identifier, schema); } catch (AlreadyExistsException e) { if (catalog.viewExists(identifier)) { /* resolve collision: rename or drop view */ } }

Prevention

When it happens

Trigger: createTable() called for an identifier that was previously registered as a view in a V1 JDBC catalog; a table/view name collision after migrating a catalog from V0 to V1; SQL CREATE TABLE issued where a CREATE VIEW already registered the name.

Common situations: Legacy JDBC catalogs (schema V1) shared by engines creating both views and tables; name collisions after database consolidation; users unaware that old JDBC catalogs stored views in the table record store.

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/33eb3b93ca2c950b. Report an issue: GitHub.