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

  1. 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).
  2. Qualify the statement with the Iceberg catalog name: `ALTER TABLE iceberg_catalog.db.t ADD PARTITION FIELD ...`.
  3. Use the target engine's own partitioning API if the table genuinely is not an Iceberg table.
  4. 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

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


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)