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

ExtendedDataSourceV2Strategy throws IcebergAnalysisException when ALTER TABLE ... RENAME TO (on a view) resolves the destination to a different catalog than the source. Spark's RenameTable on ViewCatalog only supports renaming within the same catalog; cross-catalog moves are not implemented, so the plan is rejected before execution.

Source

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

    case SetIdentifierFields(IcebergCatalogAndIdentifier(catalog, ident), fields) =>
      SetIdentifierFieldsExec(catalog, ident, fields) :: Nil

    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()}")
      }
      RenameV2ViewExec(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,
          queryColumnNames,
          comment,
          properties,
          allowExisting,
          replace,

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Rename within the same catalog: qualify the new name with the same catalog as the source.
  2. If a cross-catalog move is needed, create the view in the target catalog (CREATE VIEW ... AS SELECT) and drop the original.
  3. Check how the new name is parsed via Spark3Util.catalogAndIdentifier — use a fully qualified name to avoid accidental session-catalog resolution.
  4. Include the full catalog.ns prefix in the new identifier.

Example fix

// before
ALTER VIEW iceberg_catalog.db.events_v RENAME TO session_catalog.db.events_v;
// after
ALTER VIEW iceberg_catalog.db.events_v RENAME TO iceberg_catalog.db.events_v2;
Defensive patterns

Strategy: validation

Validate before calling

val (newCatalog, _) = Spark3Util.catalogAndIdentifier(spark, newName)
if (newCatalog.name() != sourceCatalogName)
  throw new IllegalArgumentException("Rename cannot move a view across catalogs; create a new view instead")

Type guard

def sameCatalog(oldName: String, newName: String): Boolean =
  Spark3Util.catalogAndIdentifier(spark, newName).catalog().name() ==
    Spark3Util.catalogAndIdentifier(spark, oldName).catalog().name()

Try / catch

try { spark.sql(s"ALTER VIEW $oldName RENAME TO $newName") } catch { case e: IcebergAnalysisException if e.getMessage.startsWith("Cannot move view between catalogs") => // fall back to create-then-drop across catalogs }

Prevention

When it happens

Trigger: ALTER VIEW old_catalog.ns.v RENAME TO other_catalog.ns.v2 where Spark3Util.catalogAndIdentifier resolves `other_catalog` as the destination catalog name differing from oldCatalog.name.

Common situations: Unqualified RENAME TO names that default to the session catalog while the view lives in a named Iceberg catalog; intentional cross-catalog reorganization attempts; copy-pasted rename statements that drop the catalog prefix.

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