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
- Rename within the same catalog: qualify the new name with the same catalog as the source.
- If a cross-catalog move is needed, create the view in the target catalog (CREATE VIEW ... AS SELECT) and drop the original.
- Check how the new name is parsed via Spark3Util.catalogAndIdentifier — use a fully qualified name to avoid accidental session-catalog resolution.
- 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
- Always use fully qualified catalog.namespace.view names in RENAME TO
- Never assume RENAME TO without a catalog prefix stays in the source catalog
- For cross-catalog reorganization, use CREATE VIEW AS SELECT then DROP VIEW
- Test rename statements with Spark3Util.catalogAndIdentifier resolution before running in prod
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
- Cannot move view between catalogs: from=${oldCatalog.name} a
- View does not exist: fromIdentifier
- View already exists: toIdentifier
- NoSuchViewException(fromIdentifier)
- ViewAlreadyExistsException(toIdentifier)
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/2652cc26cae7b4e7.
Report an issue: GitHub.