{"record":{"id":"155718494b0c71df","repo":"apache/iceberg","slug":"cannot-drop-branch-on-non-iceberg-table-table-155718","errorCode":null,"errorMessage":"Cannot drop branch on non-Iceberg table: $table","messagePattern":"Cannot drop branch on non-Iceberg table: \\$table","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spark/v4.2/spark-extensions/src/main/scala/org/apache/spark/sql/execution/datasources/v2/DropBranchExec.scala","lineNumber":47,"sourceCode":"    ident: Identifier,\n    branch: String,\n    ifExists: Boolean)\n    extends LeafV2CommandExec {\n\n  import org.apache.spark.sql.connector.catalog.CatalogV2Implicits._\n\n  override lazy val output: Seq[Attribute] = Nil\n\n  override protected def run(): Seq[InternalRow] = {\n    catalog.loadTable(ident) match {\n      case iceberg: SparkTable =>\n        val ref = iceberg.table().refs().get(branch)\n        if (ref != null || !ifExists) {\n          iceberg.table().manageSnapshots().removeBranch(branch).commit()\n        }\n\n      case table =>\n        throw new UnsupportedOperationException(s\"Cannot drop branch on non-Iceberg table: $table\")\n    }\n\n    Nil\n  }\n\n  override def simpleString(maxFields: Int): String = {\n    s\"DropBranch branch: ${branch} for table: ${ident.quoted}\"\n  }\n}\n","sourceCodeStart":29,"sourceCodeEnd":57,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.2/spark-extensions/src/main/scala/org/apache/spark/sql/execution/datasources/v2/DropBranchExec.scala#L29-L57","documentation":"This UnsupportedOperationException is thrown by Spark's DROP BRANCH execution when the resolved table is not an Iceberg table. Removing snapshot references (branches) is only supported on Iceberg tables; the non-Iceberg case falls to the default match and throws. Note the related NoSuchNamespaceException/NoSuchRefException path handles missing branches on Iceberg tables separately.","triggerScenarios":"Running 'ALTER TABLE ... DROP BRANCH ...' where the table resolves to a non-Iceberg Spark table, e.g. through a Delta or Hive catalog.","commonSituations":"Table created in a non-Iceberg format but referenced without catalog qualification; catalog alias misconfiguration; copy-paste of Iceberg DDL onto another provider's table.","solutions":["Ensure the table is an Iceberg table before issuing DROP BRANCH","Qualify with the Iceberg catalog: ALTER TABLE iceberg_catalog.db.tbl DROP BRANCH b1","Check catalog registration in Spark conf","Add IF EXISTS only guards missing branches; it does not make non-Iceberg tables supported"],"exampleFix":"// before (generic catalog)\nALTER TABLE my_table DROP BRANCH audit;\n// after\nALTER TABLE iceberg_catalog.db.my_table DROP BRANCH audit;","handlingStrategy":"validation","validationCode":"val icebergTable = Spark3Util.loadIcebergTable(spark, fullTableName)\nrequire(icebergTable != null, s\"$fullTableName is not an Iceberg table\")","typeGuard":"def isIcebergTable(spark: SparkSession, name: String): Boolean =\n  scala.util.Try(Spark3Util.loadIcebergTable(spark, name)).map(_ != null).getOrElse(false)","tryCatchPattern":null,"preventionTips":["Only issue DROP BRANCH on Iceberg tables","Qualify with the Iceberg catalog name","Add IF EXISTS to tolerate missing branches, remembering it does not fix non-Iceberg targets"],"tags":["spark","iceberg","unsupported-operation","branch"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}