apache/iceberg · error · AlreadyExistsException

View with same name already exists: %s

Error message

View with same name already exists: %s

What it means

During a table's first commit (doCommit with base == null), InMemoryCatalog checks whether a view is already registered under the same identifier. Iceberg keeps tables and views in separate maps but shares one identifier namespace, so creating a table over an existing view name would collide; it throws AlreadyExistsException to preserve the invariant.

Source

Thrown at core/src/main/java/org/apache/iceberg/inmemory/InMemoryCatalog.java:438

      } else {
        refreshFromMetadataLocation(latestLocation);
      }
    }

    @Override
    public void doCommit(TableMetadata base, TableMetadata metadata) {
      String newLocation = writeNewMetadataIfRequired(base == null, metadata);
      String oldLocation = base == null ? null : base.metadataFileLocation();

      synchronized (InMemoryCatalog.this) {
        if (null == base && !namespaceExists(tableIdentifier.namespace())) {
          throw new NoSuchNamespaceException(
              "Cannot create table %s. Namespace does not exist: %s",
              tableIdentifier, tableIdentifier.namespace());
        }

        if (views.containsKey(tableIdentifier)) {
          throw new AlreadyExistsException(
              "View with same name already exists: %s", tableIdentifier);
        }

        tables.compute(
            tableIdentifier,
            (k, existingLocation) -> {
              if (!Objects.equal(existingLocation, oldLocation)) {
                if (null == base) {
                  throw new AlreadyExistsException("Table already exists: %s", tableName());
                }

                if (null == existingLocation) {
                  throw new NoSuchTableException("Table does not exist: %s", tableName());
                }

                throw new CommitFailedException(
                    "Cannot commit to table %s metadata location from %s to %s "
                        + "because it has been concurrently modified to %s",

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Check catalog.viewExists(ident) before createTable and drop the view if replacement is intended.
  2. Pick a distinct name for the table.
  3. Register the table in a different namespace to avoid the shared-name collision.

Example fix

// before
catalog.createTable(ident, schema);

// after
if (catalog.viewExists(ident)) {
  catalog.dropView(ident); // only if replacement is intended
}
catalog.createTable(ident, schema);
Defensive patterns

Strategy: validation

Validate before calling

if (catalog.viewExists(ident)) { throw new IllegalStateException("View occupies table name: " + ident); }

Try / catch

try { catalog.createTable(ident, schema); } catch (AlreadyExistsException e) { // inspect whether a view holds the name and resolve }

Prevention

When it happens

Trigger: catalog.createTable(ident, ...) or any initial table commit where views.containsKey(ident) is true — i.e. a view with the same fully-qualified name exists.

Common situations: Recreating a table after it was replaced by a view of the same name; name collisions between teams sharing a namespace; scripts that drop tables but the name was re-registered as a view.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/6ecc9ec3bc0305e1. Report an issue: GitHub.