apache/iceberg · error · IcebergAnalysisException

Cannot move view between catalogs: from=${oldCatalog.name} a

Error message

Cannot move view between catalogs: from=${oldCatalog.name} and to=${newIdent.catalog().name()}

What it means

This IcebergAnalysisException is thrown by ExtendedDataSourceV2Strategy during RENAME VIEW resolution when the source view's catalog differs from the catalog parsed from the new name. Spark's ViewCatalog rename semantics do not support moving a view across catalogs, so the strategy rejects it up front.

Source

Thrown at spark/v4.2/spark-extensions/src/main/scala/org/apache/spark/sql/execution/datasources/v2/ExtendedDataSourceV2Strategy.scala:130

    case DropIdentifierFields(IcebergCatalogAndIdentifier(catalog, ident), fields) =>
      DropIdentifierFieldsExec(catalog, ident, fields) :: Nil

    case SetWriteDistributionAndOrdering(
          IcebergCatalogAndIdentifier(catalog, ident),
          distributionMode,
          ordering) =>
      SetWriteDistributionAndOrderingExec(catalog, ident, distributionMode, ordering) :: Nil

    case OrderAwareCoalesce(numPartitions, coalescer, child) =>
      OrderAwareCoalesceExec(numPartitions, coalescer, planLater(child)) :: Nil

    case RenameTable(
          ResolvedV2View(oldCatalog: ViewCatalog, oldIdent, _),
          newName,
          isView @ true) =>
      val newIdent = Spark3Util.catalogAndIdentifier(spark, newName.toList.asJava)
      if (oldCatalog.name != newIdent.catalog().name()) {
        throw new IcebergAnalysisException(
          s"Cannot move view between catalogs: from=${oldCatalog.name} and to=${newIdent.catalog().name()}")
      }
      IcebergRenameV2ViewExec(oldCatalog, oldIdent, newIdent.identifier()) :: Nil

    case DropIcebergView(ResolvedIdentifier(viewCatalog: ViewCatalog, ident), ifExists) =>
      DropV2ViewExec(viewCatalog, ident, ifExists) :: Nil

    case CreateIcebergView(
          ResolvedIdentifier(viewCatalog: ViewCatalog, ident),
          queryText,
          query,
          columnAliases,
          columnComments,
          comment,
          collation,
          properties,
          allowExisting,
          replace,

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Rename within the same catalog: keep the target name in the same catalog as the source
  2. Drop the view from the source catalog and recreate it in the target catalog to move it
  3. Check the session's current catalog so an unqualified target resolves to the intended one
  4. Use Spark3Util.catalogAndIdentifier output to confirm which catalog the new name resolves to

Example fix

// before: cross-catalog move
ALTER VIEW iceberg_cat.db.v RENAME TO spark_catalog.db.v2;
// after: rename within one catalog
ALTER VIEW iceberg_cat.db.v RENAME TO iceberg_cat.db.v2;
Defensive patterns

Strategy: validation

Validate before calling

val (newCat, newIdent) = Spark3Util.catalogAndIdentifier(spark, newNameParts.asJava)
require(newCat.name() == oldCatalog.name,
  "View rename must stay within the same catalog; drop and recreate to move across catalogs")

Try / catch

try { spark.sql("ALTER VIEW ... RENAME TO ...") } catch {
  case e: org.apache.iceberg.spark.IcebergAnalysisException =>
    logError("rename crosses catalogs; drop + recreate instead", e)
}

Prevention

When it happens

Trigger: Running 'ALTER VIEW old_catalog.db.v RENAME TO other_catalog.db.v2' where the new identifier's catalog name differs from the old catalog's name.

Common situations: Unqualified rename targets defaulting to a different session catalog; typos in the target catalog name; attempting to migrate views between catalogs with a single rename.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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