apache/iceberg · error · UnsupportedOperationException
Cannot add partition field to non-Iceberg table: $table
Error message
Cannot add partition field to non-Iceberg table: $table
What it means
AddPartitionFieldExec applies partition-field evolution only when the resolved table is an Iceberg table exposing updateSpec(); for any other V2 catalog table the command pattern-match falls through and throws UnsupportedOperationException, because spec evolution has no meaning outside Iceberg's partition-spec model.
Solutions
- Confirm the table is in an Iceberg catalog: run DESCRIBE TABLE / check the catalog implementation in your Spark session config (spark.sql.catalog.<name>=org.apache.iceberg.spark.SparkCatalog).
- Qualify the statement with the Iceberg catalog name: `ALTER TABLE iceberg_catalog.db.t ADD PARTITION FIELD ...`.
- Use the target engine's own partitioning API if the table genuinely is not an Iceberg table.
- If the table should be Iceberg, migrate/register it (e.g. via snapshot/import procedures) before evolving its spec.
Example fix
-- before ALTER TABLE spark_catalog.default.t ADD PARTITION FIELD days(ts) -- after ALTER TABLE iceberg_cat.default.t ADD PARTITION FIELD days(ts)
Defensive patterns
Strategy: validation
Validate before calling
// Ensure the target catalog is Iceberg before ADD PARTITION FIELD val isIceberg = spark.conf.get(s"spark.sql.catalog.$catName") == "org.apache.iceberg.spark.SparkCatalog" require(isIceberg, s"Catalog $catName is not an Iceberg catalog")
Try / catch
try { spark.sql(s"ALTER TABLE $t ADD PARTITION FIELD days(ts)") } catch {
case e: UnsupportedOperationException if e.getMessage.contains("non-Iceberg table") =>
log.error(s"$t is not an Iceberg table; migrate or qualify with the Iceberg catalog name")
} Prevention
- Qualify tables with the Iceberg catalog name in DDL
- Verify catalog configs (spark.sql.catalog.*) point to SparkCatalog/SparkSessionCatalog
- Use DESCRIBE EXTENDED to confirm table provider before spec evolution
- Register/migrate external tables into Iceberg before evolving their partition spec
When it happens
Trigger: Running `ALTER TABLE <v2_table> ADD PARTITION FIELD <transform>` where <v2_table> is backed by a non-Iceberg catalog (e.g. a Delta/JDBC/custom V2 catalog) so the Exec resolves to a generic table rather than an org.apache.iceberg.Table.
Common situations: Pointing ALTER TABLE ... ADD PARTITION FIELD at the wrong catalog or table type; running the Iceberg extension syntax against tables registered via Spark's generic V2 catalog; typos in catalog qualification so the Iceberg catalog isn't selected.
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 drop partition field in non-Iceberg table: $table
- Altering a view is not supported by catalog:
- Altering a view is not supported by catalog
- 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/1d48afd7214a9f3b.
Report an issue: GitHub.
Appendix: source
Thrown at spark/v4.2/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)