{"record":{"id":"8f7ba226dd2e16ef","repo":"apache/iceberg","slug":"cannot-create-or-replace-branch-on-non-iceberg-tab-8f7ba2","errorCode":null,"errorMessage":"Cannot create or replace branch on non-Iceberg table: $table","messagePattern":"Cannot create or replace branch on non-Iceberg table: \\$table","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spark/v4.1/spark-extensions/src/main/scala/org/apache/spark/sql/execution/datasources/v2/CreateOrReplaceBranchExec.scala","lineNumber":93,"sourceCode":"          safeCreateBranch()\n        }\n\n        if (branchOptions.numSnapshots.nonEmpty) {\n          manageSnapshots.setMinSnapshotsToKeep(branch, branchOptions.numSnapshots.get.toInt)\n        }\n\n        if (branchOptions.snapshotRetain.nonEmpty) {\n          manageSnapshots.setMaxSnapshotAgeMs(branch, branchOptions.snapshotRetain.get)\n        }\n\n        if (branchOptions.snapshotRefRetain.nonEmpty) {\n          manageSnapshots.setMaxRefAgeMs(branch, branchOptions.snapshotRefRetain.get)\n        }\n\n        manageSnapshots.commit()\n\n      case table =>\n        throw new UnsupportedOperationException(\n          s\"Cannot create or replace branch on non-Iceberg table: $table\")\n    }\n\n    Nil\n  }\n\n  override def simpleString(maxFields: Int): String = {\n    s\"CreateOrReplace branch: $branch for table: ${ident.quoted}\"\n  }\n}\n","sourceCodeStart":75,"sourceCodeEnd":104,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.1/spark-extensions/src/main/scala/org/apache/spark/sql/execution/datasources/v2/CreateOrReplaceBranchExec.scala#L75-L104","documentation":"CreateOrReplaceBranchExec applies WAP/branch management (manageSnapshots.createOrReplaceBranch...) only when the resolved table is an Iceberg table. Non-Iceberg Table implementations hit the default case and throw this UnsupportedOperationException because snapshot references (branches) do not exist outside Iceberg.","triggerScenarios":"Running `ALTER TABLE ... CREATE OR REPLACE BRANCH ...` against a table resolved through a non-Iceberg catalog (plain Spark V2 datasource tables, Hive tables, Delta tables, etc.).","commonSituations":"Wrong catalog in a multi-catalog environment, table names without the Iceberg catalog prefix resolving to spark_catalog, or assuming a foreign format supports Iceberg branching.","solutions":["Qualify the table with the Iceberg catalog: `ALTER TABLE iceberg_catalog.db.t CREATE OR REPLACE BRANCH b ...`.","Confirm the catalog config: spark.sql.catalog.<name>=org.apache.iceberg.spark.SparkCatalog.","Verify the target table's format is Iceberg; migrate it if branching is required.","If the goal is versioning on a non-Iceberg table, use that engine's own mechanism (e.g. Delta branches) instead."],"exampleFix":"-- before\nALTER TABLE spark_catalog.db.t CREATE OR REPLACE BRANCH audit\n-- after\nALTER TABLE iceberg_catalog.db.t CREATE OR REPLACE BRANCH audit","handlingStrategy":"type-guard","validationCode":"// Scala: confirm catalog is Iceberg before branch DDL\nrequire(\n  spark.conf.getOption(s\"spark.sql.catalog.$catalogName\")\n    .exists(_.contains(\"org.apache.iceberg.spark.SparkCatalog\")),\n  s\"$catalogName is not an Iceberg catalog\")","typeGuard":"// Scala\n table match {\n  case st: org.apache.iceberg.spark.SparkTable => st.table() // Iceberg table\n  case _ => null // branch DDL unsupported\n}","tryCatchPattern":"// Scala\ntry {\n  spark.sql(s\"ALTER TABLE $ident CREATE OR REPLACE BRANCH $branch\")\n} catch {\n  case _: UnsupportedOperationException => log.error(s\"$ident is not Iceberg; branching unavailable\")\n}","preventionTips":["Use fully-qualified names with the Iceberg catalog in all branch DDL.","Filter mixed-format table inventories to Iceberg tables before batch operations.","Verify catalog configuration in spark-defaults.conf or session builder."],"tags":["spark","branching","non-iceberg-table","unsupported-operation"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}