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 implements `ALTER TABLE ... CREATE OR REPLACE BRANCH` only for Iceberg tables. When the target table is any other V2 table provider, the executor throws UnsupportedOperationException since WapSnapshot/manageSnapshots branch management is an Iceberg-only capability.
Source
Thrown at spark/v4.0/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)
Solutions
- Target the table via an Iceberg catalog alias (e.g. iceberg_catalog.db.t)
- Configure the catalog with spark.sql.catalog.<name>=org.apache.iceberg.spark.SparkCatalog
- Verify with DESCRIBE TABLE / catalog metadata that the table is an Iceberg table before running branch DDL
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: try-catch
Validate before calling
val catalogImpl = spark.conf.get(s"spark.sql.catalog.$catalogName") require(catalogImpl == "org.apache.iceberg.spark.SparkCatalog" || catalogImpl == "org.apache.iceberg.spark.SparkSessionCatalog", "Branch DDL requires an Iceberg catalog")
Type guard
def isIcebergTable(t: Table): Boolean = t.isInstanceOf[IcebergTable]
Try / catch
try { spark.sql(ddl) } catch { case _: UnsupportedOperationException => log.error("CREATE OR REPLACE BRANCH requires an Iceberg table") } Prevention
- Use an Iceberg catalog alias for branching/branch DDL
- Confirm the catalog implementation class in Spark conf
- Validate table format before issuing Iceberg ref-management statements
When it happens
Trigger: Running `ALTER TABLE catalog.db.t CREATE OR REPLACE BRANCH b ...` where t resolves to a non-Iceberg table (non-Iceberg catalog implementation, spark_catalog table, etc.).
Common situations: Using the default spark_catalog or another provider's catalog while running Iceberg branching DDL; misconfigured catalog class; assuming the extension SQL works on any table format.
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
- Renaming a view is not supported by catalog: ${catalogName}
- Cannot convert predicate to SQL: <pred>
- Cannot convert term to SQL: <term>
- Cannot retrieve UUID for table <table.name()>
- Unsupported task group for row-based reads: ${partition.task
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/dfd509d645c9f7c1.
Report an issue: GitHub.