apache/iceberg · error

Cannot set write order of non-Iceberg table: $table

Error message

Cannot set write order of non-Iceberg table: $table

What it means

Iceberg's SetWriteDistributionAndOrderingExec only supports applying write distribution/ordering to tables backed by an Iceberg catalog. If the resolved table is any other DataSource V2 table (or cannot be cast to Iceberg's Table/transaction interface), the executor throws this UnsupportedOperationException. It exists because write order is an Iceberg table-property concept with no meaning for other table implementations.

Solutions

  1. Verify the catalog backing the table is an Iceberg catalog (spark_catalog or a catalog with org.apache.iceberg.spark.SparkCatalog)
  2. Set spark.sql.catalog.<name>=org.apache.iceberg.spark.SparkCatalog and spark.sql.catalog.<name>.<format>=iceberg or a catalog-impl
  3. Migrate the table to Iceberg before setting write order (e.g. via Spark procedure migrate/snapshot or rewrite)

Example fix

// before
spark.sql("ALTER TABLE jdbctable WRITE ORDERED BY id") // throws
// after
spark.sql("ALTER TABLE iceberg_table WRITE ORDERED BY id") // table in an Iceberg catalog
Defensive patterns

Strategy: validation

Validate before calling

val catalogImpl = spark.conf.get(s"spark.sql.catalog.$catalogName", "")
if (!catalogImpl.contains("org.apache.iceberg")) {
  throw new IllegalStateException(s"Catalog $catalogName is not an Iceberg catalog")
}

Type guard

def isIcebergTable(t: Table): Boolean = t.isInstanceOf[org.apache.iceberg.spark.source.SparkTable] && t.asInstanceOf[SparkTable].table() != null

Try / catch

try {
  spark.sql(s"ALTER TABLE $name WRITE ORDERED BY id")
} catch {
  case e: UnsupportedOperationException if e.getMessage.contains("Cannot set write order of non-Iceberg table") =>
    logError(s"$name is not an Iceberg table; skipping write order", e)
}

Prevention

When it happens

Trigger: Running ALTER TABLE ... SET TBLPROPERTIES or the WRITE ORDERED BY / WRITE DISTRIBUTED BY SQL commands against a table resolved from a non-Iceberg catalog (e.g. a generic Spark V2 catalog like the built-in JDBC or another format's catalog).

Common situations: Pointing spark.sql.catalog.<name> at a non-Iceberg catalog implementation and then attempting to set Iceberg write order; running Iceberg extensions SQL against a view or temporary table; catalog name typo causing fallback to the session catalog.

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/79dcfe21d885c866. Report an issue: GitHub.

Appendix: source

Thrown at spark/v3.5/spark-extensions/src/main/scala/org/apache/spark/sql/execution/datasources/v2/SetWriteDistributionAndOrderingExec.scala:69

        sortOrder.foreach {
          case (term, SortDirection.ASC, nullOrder) =>
            orderBuilder.asc(term, nullOrder)
          case (term, SortDirection.DESC, nullOrder) =>
            orderBuilder.desc(term, nullOrder)
        }
        orderBuilder.commit()

        distributionMode.foreach { mode =>
          txn
            .updateProperties()
            .set(WRITE_DISTRIBUTION_MODE, mode.modeName())
            .commit()
        }

        txn.commitTransaction()

      case table =>
        throw new UnsupportedOperationException(
          s"Cannot set write order of non-Iceberg table: $table")
    }

    Nil
  }

  override def simpleString(maxFields: Int): String = {
    val tableIdent = s"${catalog.name}.${ident.quoted}"
    val order = sortOrder
      .map { case (term, direction, nullOrder) =>
        s"$term $direction $nullOrder"
      }
      .mkString(", ")
    s"SetWriteDistributionAndOrdering $tableIdent $distributionMode $order"
  }
}

View on GitHub (pinned to 86d9c8fc54)