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

  1. Fix the sort-order expression syntax: valid form e.g. 'id ASC NULLS FIRST, truncate(10, name) DESC' with existing columns and Iceberg transforms.
  2. Validate column names against the table schema before submitting the order string.
  3. Verify the Spark session's SQL parser is the default SparkSQLParser (Iceberg's ExtendedParser wraps it); custom parser plugins can break detection.
  4. 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

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.

Related errors


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