apache/iceberg · error · UnsupportedOperationException
Cannot create or replace branch on non-Iceberg table: $table
Error message
Cannot create or replace branch on non-Iceberg table: $table
What it means
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.
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.
Example fix
-- before ALTER TABLE spark_catalog.db.t CREATE OR REPLACE BRANCH audit -- after ALTER TABLE iceberg_catalog.db.t CREATE OR REPLACE BRANCH audit
Defensive patterns
Strategy: type-guard
Validate before calling
// Scala: confirm catalog is Iceberg before branch DDL
require(
spark.conf.getOption(s"spark.sql.catalog.$catalogName")
.exists(_.contains("org.apache.iceberg.spark.SparkCatalog")),
s"$catalogName is not an Iceberg catalog") Type guard
// Scala
table match {
case st: org.apache.iceberg.spark.SparkTable => st.table() // Iceberg table
case _ => null // branch DDL unsupported
} Try / catch
// Scala
try {
spark.sql(s"ALTER TABLE $ident CREATE OR REPLACE BRANCH $branch")
} catch {
case _: UnsupportedOperationException => log.error(s"$ident is not Iceberg; branching unavailable")
} Prevention
- 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.
When it happens
Trigger: 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.).
Common situations: 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.
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 add partition field to non-Iceberg table: $table
- Cannot create or replace branch on non-Iceberg table: $table
- Cannot create tag to non-Iceberg table: $table
- Altering a view is not supported by catalog:
- Altering a view is not supported by catalog
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/8f7ba226dd2e16ef.
Report an issue: GitHub.
Appendix: source
Thrown at spark/v4.1/spark-extensions/src/main/scala/org/apache/spark/sql/execution/datasources/v2/CreateOrReplaceBranchExec.scala:93
safeCreateBranch()
}
if (branchOptions.numSnapshots.nonEmpty) {
manageSnapshots.setMinSnapshotsToKeep(branch, branchOptions.numSnapshots.get.toInt)
}
if (branchOptions.snapshotRetain.nonEmpty) {
manageSnapshots.setMaxSnapshotAgeMs(branch, branchOptions.snapshotRetain.get)
}
if (branchOptions.snapshotRefRetain.nonEmpty) {
manageSnapshots.setMaxRefAgeMs(branch, branchOptions.snapshotRefRetain.get)
}
manageSnapshots.commit()
case table =>
throw new UnsupportedOperationException(
s"Cannot create or replace branch on non-Iceberg table: $table")
}
Nil
}
override def simpleString(maxFields: Int): String = {
s"CreateOrReplace branch: $branch for table: ${ident.quoted}"
}
}
View on GitHub (pinned to 86d9c8fc54)