{"record":{"id":"80ee60e6eed15e96","repo":"apache/iceberg","slug":"cannot-specify-the-sort-order-because-it-s-a-res","errorCode":null,"errorMessage":"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.","messagePattern":"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\\.","errorType":"exception","errorClass":"java.lang.UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/SparkCatalog.java","lineNumber":341,"sourceCode":"  @Override\n  public Table alterTable(Identifier ident, TableChange... changes) throws NoSuchTableException {\n    SetProperty setLocation = null;\n    SetProperty setSnapshotId = null;\n    SetProperty pickSnapshotId = null;\n    List<TableChange> propertyChanges = Lists.newArrayList();\n    List<TableChange> schemaChanges = Lists.newArrayList();\n\n    for (TableChange change : changes) {\n      if (change instanceof SetProperty) {\n        SetProperty set = (SetProperty) change;\n        if (TableCatalog.PROP_LOCATION.equalsIgnoreCase(set.property())) {\n          setLocation = set;\n        } else if (\"current-snapshot-id\".equalsIgnoreCase(set.property())) {\n          setSnapshotId = set;\n        } else if (\"cherry-pick-snapshot-id\".equalsIgnoreCase(set.property())) {\n          pickSnapshotId = set;\n        } else if (\"sort-order\".equalsIgnoreCase(set.property())) {\n          throw new UnsupportedOperationException(\n              \"Cannot specify the 'sort-order' because it's a reserved table \"\n                  + \"property. Please use the command 'ALTER TABLE ... WRITE ORDERED BY' to specify write sort-orders.\");\n        } else if (\"identifier-fields\".equalsIgnoreCase(set.property())) {\n          throw new UnsupportedOperationException(\n              \"Cannot specify the 'identifier-fields' because it's a reserved table property. \"\n                  + \"Please use the command 'ALTER TABLE ... SET IDENTIFIER FIELDS' to specify identifier fields.\");\n        } else {\n          propertyChanges.add(set);\n        }\n      } else if (change instanceof RemoveProperty) {\n        propertyChanges.add(change);\n      } else if (change instanceof ColumnChange) {\n        schemaChanges.add(change);\n      } else {\n        throw new UnsupportedOperationException(\"Cannot apply unknown table change: \" + change);\n      }\n    }\n","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/SparkCatalog.java#L323-L359","documentation":"Iceberg reserves the 'sort-order' table property for its internal sort-order metadata, so it cannot be set as a plain property via ALTER TABLE ... SET TBLPROPERTIES. SparkCatalog.alterTable rejects it with this UnsupportedOperationException and points to the dedicated syntax instead.","triggerScenarios":"ALTER TABLE ... SET TBLPROPERTIES ('sort-order'='...') on an Iceberg table; Spark sends the change to SparkCatalog.alterTable, which matches the reserved key case-insensitively at line 341 and throws.","commonSituations":"Migrating SQL that set sort order via properties in other engines; copying DDL from older Iceberg versions or non-Iceberg tables; LLM/templates generating SET TBLPROPERTIES for sort order.","solutions":["Use ALTER TABLE ... WRITE ORDERED BY col1, col2 [ASC|DESC] to set write sort order.","Remove 'sort-order' from SET TBLPROPERTIES and apply it via the write distribution/order clauses.","Use DataFrameWriterV2 with Spark 3.4+ ordered writes where applicable.","Inspect existing sort order with DESCRIBE TABLE / the sort-order metadata instead of the property."],"exampleFix":"// before\nALTER TABLE db.events SET TBLPROPERTIES ('sort-order'='id ASC')\n// after\nALTER TABLE db.events WRITE ORDERED BY id ASC","handlingStrategy":"validation","validationCode":"Set<String> reserved = Set.of(\"sort-order\", \"identifier-fields\"); props.keySet().removeAll(reserved.stream().map(k -> k).filter(reserved::contains).collect(java.util.stream.Collectors.toSet()));","typeGuard":"null","tryCatchPattern":"try { spark.sql(alterSql); } catch (UnsupportedOperationException e) { /* route to WRITE ORDERED BY */ }","preventionTips":["Never set reserved Iceberg properties via TBLPROPERTIES.","Use WRITE ORDERED BY / WRITE DISTRIBUTED BY for sort and distribution.","Review generated DDL for reserved keys before execution."],"tags":["spark","alter-table","reserved-property","sort-order"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}