apache/iceberg · error · AlreadyExistsException

View with same name already exists: %s

Error message

View with same name already exists: %s

What it means

An AlreadyExistsException thrown by the view Builder's replaceTransaction() in RESTSessionCatalog when a view with the same identifier already exists on the server. replaceTransaction is meant to atomically replace an existing view; if the name resolves to a view, the operation conflicts and is rejected before sending the replacement request.

Source

Thrown at core/src/main/java/org/apache/iceberg/rest/RESTSessionCatalog.java:1068

                  tableConf,
                  response.credentials(),
                  response.remoteSigningConfig()),
              RESTTableOperations.UpdateType.CREATE,
              createChanges(meta),
              meta,
              endpoints);

      trackFileIO(ops);

      return Transactions.createTableTransaction(
          fullName, ops, meta, metricsReporter(paths.metrics(ident), tableClient));
    }

    @Override
    public Transaction replaceTransaction() {
      Endpoint.check(endpoints, Endpoint.V1_UPDATE_TABLE);
      if (viewExists(context, ident)) {
        throw new AlreadyExistsException("View with same name already exists: %s", ident);
      }

      LoadTableResponse response = loadInternal(context, ident, snapshotMode, Map.of(), h -> {});

      String fullName = fullTableName(ident);

      Map<String, String> tableConf = response.config();
      AuthSession contextualSession = authManager.contextualSession(context, catalogAuth);
      AuthSession tableSession = authManager.tableSession(ident, tableConf, contextualSession);
      TableMetadata base = response.tableMetadata();

      propertiesBuilder.putAll(tableOverrideProperties());
      Map<String, String> tableProperties = propertiesBuilder.buildKeepingLast();
      TableMetadata replacement =
          base.buildReplacement(
              schema,
              spec != null ? spec : PartitionSpec.unpartitioned(),
              writeOrder != null ? writeOrder : SortOrder.unsorted(),

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Check catalog.viewExists(identifier) first and decide whether replace, create, or drop is intended.
  2. Catch org.apache.iceberg.exceptions.AlreadyExistsException and handle the conflict explicitly.
  3. Use dropView then createView if unconditional replacement semantics are desired (non-atomically).
  4. Verify the identifier/namespace resolution — the existing view may be under a different resolved namespace than expected.

Example fix

// before
viewBuilder(ident).replaceTransaction().commitTransaction();
// after
if (!catalog.viewExists(ident)) { /* create */ } else { catalog.loadView(ident).replace().commit(); }
Defensive patterns

Strategy: validation

Validate before calling

if (catalog.viewExists(identifier)) { /* handle existing view: replace() vs skip vs drop */ }

Try / catch

try { builder.replaceTransaction().commitTransaction(); } catch (AlreadyExistsException e) { /* view already exists: resolve conflict */ }

Prevention

When it happens

Trigger: Calling viewBuilder(...).replaceTransaction() (or SQL CREATE OR REPLACE via this path) when viewExists(context, ident) is true — i.e., the target name is an existing view.

Common situations: Concurrent CREATE OR REPLACE VIEW statements racing on the same view name; a script that assumes the view does not exist; namespace confusion where the view already exists under a resolved default namespace.

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