apache/iceberg · error · AlreadyExistsException

View with same name already exists: %s.%s

Error message

View with same name already exists: %s.%s

What it means

HiveTableOperations.doCommit throws AlreadyExistsException when it attempts to create a new table in HMS but an entity of type VIRTUAL_VIEW with the same name already exists AND already carries the Iceberg metadata-location property — meaning a concurrent commit created it first, as a view. It protects against silently overwriting a concurrently created Iceberg view.

Source

Thrown at hive-metastore/src/main/java/org/apache/iceberg/hive/HiveTableOperations.java:283

    BaseMetastoreOperations.CommitStatus commitStatus =
        BaseMetastoreOperations.CommitStatus.FAILURE;
    boolean updateHiveTable = false;

    HiveLock lock = lockObject(base != null ? base : tableMetadata);
    try {
      lock.lock();

      Table tbl = loadHmsTable();

      if (tbl != null) {
        // If we try to create the table but the metadata location is already set, then we had a
        // concurrent commit
        if (newTable
            && tbl.getParameters().get(BaseMetastoreTableOperations.METADATA_LOCATION_PROP)
                != null) {
          if (TableType.VIRTUAL_VIEW.name().equalsIgnoreCase(tbl.getTableType())) {
            throw new AlreadyExistsException(
                "View with same name already exists: %s.%s", database, tableName);
          }
          throw new AlreadyExistsException("Table already exists: %s.%s", database, tableName);
        }

        updateHiveTable = true;
        LOG.debug("Committing existing table: {}", fullName);
      } else {
        tbl =
            newHmsTable(
                tableMetadata.property(HiveCatalog.HMS_TABLE_OWNER, HiveHadoopUtil.currentUser()));
        LOG.debug("Committing new table: {}", fullName);
      }

      tbl.setSd(
          HiveOperationsBase.storageDescriptor(
              tableMetadata.schema(),
              tableMetadata.location(),

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Catch AlreadyExistsException and re-load the view — the concurrent creation succeeded and its result is authoritative.
  2. Deduplicate creation logic so only one process creates the view (idempotent create-or-load pattern).
  3. If the concurrent view is wrong, drop it and recreate with the intended definition after coordination.

Example fix

// before
view = catalog.buildView(ident).withQuery("sql").create(); // races
// after
try { view = catalog.buildView(ident).withQuery("sql").create(); }
catch (AlreadyExistsException e) { view = catalog.loadView(ident); }
Defensive patterns

Strategy: try-catch

Validate before calling

boolean exists = catalog.viewExists(ident); // only one coordinator should create when false

Try / catch

try { view = catalog.buildView(ident).withQuery(sql).create(); } catch (AlreadyExistsException e) { view = catalog.loadView(ident); }

Prevention

When it happens

Trigger: Concurrent createView operations racing on the same identifier: both see the table as absent (newTable), but the first commit lands, so the loser's create path finds the entity with METADATA_LOCATION_PROP set and tableType VIRTUAL_VIEW.

Common situations: Two jobs or engines creating the same Iceberg view simultaneously; retry logic re-running a create after an ambiguous first attempt; duplicate scheduled jobs.

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