apache/iceberg · error · IllegalArgumentException
Unable to parse sortOrder: %s
Error message
Unable to parse sortOrder: %s
What it means
ExtendedParser.parseSortOrder delegates order-string parsing to Spark's SQL parser when it is an Iceberg ExtendedParser; if the parser raises AnalysisException the string is unparseable and it rethrows IllegalArgumentException('Unable to parse sortOrder: %s'). Used by ALTER TABLE ... WRITE ORDERED BY / ADD SORT ORDER style flows.
Source
Thrown at spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/ExtendedParser.java:63
return term;
}
public SortDirection direction() {
return direction;
}
public NullOrder nullOrder() {
return nullOrder;
}
}
static List<RawOrderField> parseSortOrder(SparkSession spark, String orderString) {
ExtendedParser extParser = findParser(spark.sessionState().sqlParser(), ExtendedParser.class);
if (extParser != null) {
try {
return extParser.parseSortOrder(orderString);
} catch (AnalysisException e) {
throw new IllegalArgumentException(
String.format("Unable to parse sortOrder: %s", orderString), e);
}
} else {
throw new IllegalStateException(
"Cannot parse order: parser is not an Iceberg ExtendedParser");
}
}
private static <T> T findParser(ParserInterface parser, Class<T> clazz) {
ParserInterface current = parser;
while (current != null) {
if (clazz.isInstance(current)) {
return clazz.cast(current);
}
current = getNextDelegateParser(current);
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Fix the sort-order expression syntax: valid form e.g. 'id ASC NULLS FIRST, truncate(10, name) DESC' with existing columns and Iceberg transforms.
- Validate column names against the table schema before submitting the order string.
- Verify the Spark session's SQL parser is the default SparkSQLParser (Iceberg's ExtendedParser wraps it); custom parser plugins can break detection.
- Test the expression interactively with a simple ALTER TABLE ... WRITE ORDERED BY before embedding it in automation.
Example fix
// before TableUtil.sortOrder(spark, table, "id asc nulls last, foo(10, name)"); // after TableUtil.sortOrder(spark, table, "id ASC NULLS FIRST, truncate(10, name) DESC");
Defensive patterns
Strategy: validation
Validate before calling
Set<String> validCols = table.schema().columns().stream().map(Types.NestedField::name).collect(Collectors.toSet()); // every field referenced in orderString must be in validCols; transforms limited to identity,bucket,truncate,year,month,day,hour
Try / catch
try { orders = ExtendedParser.parseSortOrder(spark, orderString); } catch (IllegalArgumentException e) { throw new UserInputException("Bad sort order: " + orderString, e); } Prevention
- Validate columns and transforms in sort strings against the table schema before submit
- Use canonical syntax: col ASC/DESC, NULLS FIRST/LAST, Iceberg transforms only
- Verify the session parser supports ExtendedParser (see 2397) before string parsing
When it happens
Trigger: Passing an invalid sort-order expression string (bad syntax, unknown transform like 'truncatebad(10, col)', nonexistent column, unsupported expression) to API/SQL that parses a sort order string.
Common situations: Handwritten sort strings with typos; transforms not supported by the Spark parser version; using a column that doesn't exist in the schema; copying Hive/other-engine ORDER BY syntax Iceberg doesn't accept.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Transform is not supported: ${transform}
- Cannot specify the 'sort-order' because it's a reserved tabl
- Cannot mix identity sort columns and a Zorder sort expressio
- Unable to parse sortOrder: %s
- Transform is not supported:
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/d451748348daa446.
Report an issue: GitHub.