apache/iceberg · error

Cannot drop branch on non-Iceberg table: $table

Error message

Cannot drop branch on non-Iceberg table: $table

What it means

DropBranchExec throws this UnsupportedOperationException when a DROP BRANCH statement targets a table that is not an Iceberg table. Dropping a branch requires Iceberg's manageSnapshots().removeBranch() API, which only exists on tables wrapped by SparkTable with an Iceberg backend. The plan's pattern match falls through to the non-Iceberg case and throws.

Source

Thrown at spark/v3.5/spark-extensions/src/main/scala/org/apache/spark/sql/execution/datasources/v2/DropBranchExec.scala:47

    ident: Identifier,
    branch: String,
    ifExists: Boolean)
    extends LeafV2CommandExec {

  import org.apache.spark.sql.connector.catalog.CatalogV2Implicits._

  override lazy val output: Seq[Attribute] = Nil

  override protected def run(): Seq[InternalRow] = {
    catalog.loadTable(ident) match {
      case iceberg: SparkTable =>
        val ref = iceberg.table().refs().get(branch)
        if (ref != null || !ifExists) {
          iceberg.table().manageSnapshots().removeBranch(branch).commit()
        }

      case table =>
        throw new UnsupportedOperationException(s"Cannot drop branch on non-Iceberg table: $table")
    }

    Nil
  }

  override def simpleString(maxFields: Int): String = {
    s"DropBranch branch: ${branch} for table: ${ident.quoted}"
  }
}

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Confirm the table provider is iceberg via DESC TABLE EXTENDED.
  2. Qualify the DDL with the Iceberg catalog: DROP BRANCH b IN iceberg_catalog.db.tbl.
  3. Ensure spark.sql.catalog.<name>=org.apache.iceberg.spark.SparkCatalog is configured.
  4. Use IF EXISTS if the branch/table may not support the operation during migrations.

Example fix

-- before
DROP BRANCH old_branch IN db.events; -- non-Iceberg provider
-- after
DROP BRANCH old_branch IN iceberg_catalog.db.events;
Defensive patterns

Strategy: validation

Validate before calling

val refs = try { Some(spark.sql("SELECT * FROM cat.db.tbl.refs").collect()) } catch { case _: Exception => None }; if (refs.isEmpty) println("not an Iceberg table")

Type guard

def isIcebergSparkTable(t: Any): Boolean = t.isInstanceOf[org.apache.iceberg.spark.source.SparkTable]

Try / catch

try { spark.sql("DROP BRANCH b IN cat.db.tbl") } catch { case e: UnsupportedOperationException if e.getMessage.startsWith("Cannot drop branch on non-Iceberg") => log.warn("skip non-Iceberg table") }

Prevention

When it happens

Trigger: Running DROP BRANCH <branch> [IF EXISTS] against a non-Iceberg table, i.e. the resolved table does not match `iceberg: SparkTable` in DropBranchExec.run().

Common situations: Pointing branch DDL at a Parquet/Hive/Delta table; using a catalog not registered as the Iceberg SparkCatalog; multi-catalog setups where the default catalog resolves to a non-Iceberg provider.

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/9b8ef3bc817906e4. Report an issue: GitHub.