apache/iceberg · error · ViewAlreadyExistsException

ViewAlreadyExistsException(toIdentifier)

Error message

ViewAlreadyExistsException(toIdentifier)

What it means

In renameView, when the underlying ViewCatalog throws AlreadyExistsException for the destination identifier, SparkCatalog translates it to a Spark ViewAlreadyExistsException carrying toIdentifier. The rename fails because a view with the target name already exists; catalogs refuse to silently overwrite it.

Source

Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/SparkCatalog.java:756

  @Override
  public boolean dropView(Identifier ident) {
    if (null != asViewCatalog) {
      return asViewCatalog.dropView(buildIdentifier(ident));
    }

    return false;
  }

  @Override
  public void renameView(Identifier fromIdentifier, Identifier toIdentifier)
      throws NoSuchViewException, ViewAlreadyExistsException {
    if (null != asViewCatalog) {
      try {
        asViewCatalog.renameView(buildIdentifier(fromIdentifier), buildIdentifier(toIdentifier));
      } catch (org.apache.iceberg.exceptions.NoSuchViewException e) {
        throw new NoSuchViewException(fromIdentifier);
      } catch (org.apache.iceberg.exceptions.AlreadyExistsException e) {
        throw new ViewAlreadyExistsException(toIdentifier);
      }
    } else {
      throw new UnsupportedOperationException(
          "Renaming a view is not supported by catalog: " + catalogName);
    }
  }

  @Override
  public final void initialize(String name, CaseInsensitiveStringMap options) {
    super.initialize(name, options);

    this.cacheEnabled =
        PropertyUtil.propertyAsBoolean(
            options, CatalogProperties.CACHE_ENABLED, CatalogProperties.CACHE_ENABLED_DEFAULT);

    boolean cacheCaseSensitive =
        PropertyUtil.propertyAsBoolean(
            options,

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Choose a unique target name after checking SHOW VIEWS in the target namespace.
  2. Drop the existing destination view explicitly if replacement is intended, then rename.
  3. Add existence checks to make migration scripts idempotent.

Example fix

// before
spark.sql("ALTER VIEW analytics.v RENAME TO analytics.old") // old exists
// after
spark.sql("DROP VIEW IF EXISTS analytics.old")
spark.sql("ALTER VIEW analytics.v RENAME TO analytics.old")
Defensive patterns

Strategy: try-catch

Validate before calling

if (sparkCatalog.viewExists(toIdent)) {
  throw new IllegalStateException("Destination view already exists: " + toIdent);
}

Try / catch

try {
  sparkCatalog.renameView(from, to);
} catch (ViewAlreadyExistsException e) {
  LOG.error("Rename target {} already exists", to, e); // pick new name or drop first
}

Prevention

When it happens

Trigger: ALTER VIEW src RENAME TO dst where 'dst' already names an existing view, or a rename colliding with a name created concurrently.

Common situations: Re-running an idempotent migration script; rename target chosen without checking existing views; two pipelines renaming to the same destination name.

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