apache/iceberg · error · java.lang.UnsupportedOperationException

Cannot specify the 'sort-order' because it's a reserved tabl

Error message

Cannot specify the 'sort-order' because it's a reserved table property. Please use the command 'ALTER TABLE ... WRITE ORDERED BY' to specify write sort-orders.

What it means

'sort-order' is a reserved Iceberg table property managed through dedicated DDL, not a settable property. alterTable explicitly rejects SET TBLPROPERTIES attempts to change it with this UnsupportedOperationException, directing users to ALTER TABLE ... WRITE ORDERED BY.

Source

Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/SparkCatalog.java:293

  @Override
  public Table alterTable(Identifier ident, TableChange... changes) throws NoSuchTableException {
    SetProperty setLocation = null;
    SetProperty setSnapshotId = null;
    SetProperty pickSnapshotId = null;
    List<TableChange> propertyChanges = Lists.newArrayList();
    List<TableChange> schemaChanges = Lists.newArrayList();

    for (TableChange change : changes) {
      if (change instanceof SetProperty) {
        SetProperty set = (SetProperty) change;
        if (TableCatalog.PROP_LOCATION.equalsIgnoreCase(set.property())) {
          setLocation = set;
        } else if ("current-snapshot-id".equalsIgnoreCase(set.property())) {
          setSnapshotId = set;
        } else if ("cherry-pick-snapshot-id".equalsIgnoreCase(set.property())) {
          pickSnapshotId = set;
        } else if ("sort-order".equalsIgnoreCase(set.property())) {
          throw new UnsupportedOperationException(
              "Cannot specify the 'sort-order' because it's a reserved table "
                  + "property. Please use the command 'ALTER TABLE ... WRITE ORDERED BY' to specify write sort-orders.");
        } else if ("identifier-fields".equalsIgnoreCase(set.property())) {
          throw new UnsupportedOperationException(
              "Cannot specify the 'identifier-fields' because it's a reserved table property. "
                  + "Please use the command 'ALTER TABLE ... SET IDENTIFIER FIELDS' to specify identifier fields.");
        } else {
          propertyChanges.add(set);
        }
      } else if (change instanceof RemoveProperty) {
        propertyChanges.add(change);
      } else if (change instanceof ColumnChange) {
        schemaChanges.add(change);
      } else {
        throw new UnsupportedOperationException("Cannot apply unknown table change: " + change);
      }
    }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Use ALTER TABLE ... WRITE ORDERED BY col ASC/DESC ... to define the write sort order.
  2. Remove the 'sort-order' property assignment from the SET TBLPROPERTIES clause.
  3. If only reading, fetch the current sort order via DESCRIBE TABLE EXTENDED or the table's sortOrder() API instead of setting it.
  4. Update automation scripts to use the WRITE ORDERED BY syntax for Iceberg tables.

Example fix

-- before
ALTER TABLE t SET TBLPROPERTIES ('sort-order'='id ASC');
-- after
ALTER TABLE t WRITE ORDERED BY id ASC;
Defensive patterns

Strategy: validation

Validate before calling

-- Precheck: reject reserved properties before running DDL
-- (application-side)
List<String> reserved = Arrays.asList("sort-order", "identifier-fields",
    "current-snapshot-id", "cherry-pick-snapshot-id", "format-version");
if (props.keySet().stream().anyMatch(reserved::contains)) {
  throw new IllegalArgumentException("Use dedicated DDL for reserved properties");
}

Try / catch

try {
  spark.sql(alterStatement);
} catch (UnsupportedOperationException e) {
  if (e.getMessage().contains("sort-order")) {
    // rewrite to ALTER TABLE ... WRITE ORDERED BY
  }
}

Prevention

When it happens

Trigger: ALTER TABLE ... SET TBLPROPERTIES ('sort-order'='...') on an Iceberg table via SparkCatalog.alterTable.

Common situations: Scripts copied from older Iceberg versions where sort orders were manipulated via properties; users mistaking sort-order for a normal tunable property; migration scripts writing reserved keys blindly.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/619d47054698bc08. Report an issue: GitHub.