apache/iceberg · error
Cannot add partition field to non-Iceberg table: $table
Error message
Cannot add partition field to non-Iceberg table: $table
What it means
ADD PARTITION FIELD can only operate on Iceberg tables because spec evolution is an Iceberg feature. When the resolved V2 table is any other catalog implementation (not a valid iceberg.table), an UnsupportedOperationException is thrown listing the offending table.
Solutions
- Migrate the table to Iceberg (e.g. via snapshot/migrate procedures) before altering the partition spec
- Target the correct catalog — verify the table identifier points to an Iceberg catalog, not another provider
- Use the provider's native partitioning ALTER syntax for non-Iceberg tables
Example fix
// before
CALL cat.system.snapshot('mysql_db.orders', 'iceberg_db.orders'); -- wrong catalog / still non-Iceberg table
ALTER TABLE mysql_db.orders ADD PARTITION FIELD bucket(8, order_id);
// after
ALTER TABLE iceberg_db.orders ADD PARTITION FIELD bucket(8, order_id); Defensive patterns
Strategy: validation
Validate before calling
val catalog = spark.sessionState.catalogManager.catalog("my_cat").asInstanceOf[CatalogPlugin]
val isIceberg = spark.conf.get(s"spark.sql.catalog.my_cat") == "org.apache.iceberg.spark.SparkCatalog"
require(isIceberg, "Target catalog is not an Iceberg catalog") Try / catch
try { spark.sql(alterDdl) } catch { case e: UnsupportedOperationException if e.getMessage.contains("non-Iceberg") => log.error("migrate the table to Iceberg first"); throw e } Prevention
- Confirm the table's catalog is backed by org.apache.iceberg before using Iceberg DDL extensions
- Use DESCRIBE TABLE EXTENDED to check the provider
- Migrate foreign tables with the Iceberg snapshot/migrate procedure first
When it happens
Trigger: Running ALTER TABLE ... ADD PARTITION FIELD against a non-Iceberg V2 table (e.g. a Delta or JDBC V2 catalog table) in Spark 3.5 with Iceberg extensions registered.
Common situations: Wrong catalog/provider configured for the table; users assuming all V2 tables support Iceberg partition evolution syntax.
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 drop partition field in non-Iceberg table: $table
- Cannot replace partition field in non-Iceberg table: $table
- Already closed files for partition:
- ALTER VIEW AS is not supported. Use CREATE OR REPLACE VIEW…
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/4a4706463738d2e6.
Report an issue: GitHub.
Appendix: source
Thrown at spark/v3.5/spark-extensions/src/main/scala/org/apache/spark/sql/execution/datasources/v2/AddPartitionFieldExec.scala:48
catalog: TableCatalog,
ident: Identifier,
transform: Transform,
name: Option[String])
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 =>
iceberg.table
.updateSpec()
.addField(name.orNull, Spark3Util.toIcebergTerm(transform))
.commit()
case table =>
throw new UnsupportedOperationException(
s"Cannot add partition field to non-Iceberg table: $table")
}
Nil
}
override def simpleString(maxFields: Int): String = {
s"AddPartitionField ${catalog.name}.${ident.quoted} ${name.map(n => s"$n=").getOrElse("")}${transform.describe}"
}
}
View on GitHub (pinned to 86d9c8fc54)