apache/iceberg · error · IllegalArgumentException

Unsorted order ID must be 0

Error message

Unsorted order ID must be 0

What it means

Consistency check in SortOrder.Builder.buildUnchecked: the builder has no sort fields (which by definition produces the unsorted order) but was explicitly given a non-zero orderId. Iceberg reserves order ID 0 for the unsorted order, so an empty field list with any other ID is contradictory and rejected.

Solutions

  1. Omit the order ID so the builder defaults correctly for unsorted orders
  2. Pass orderId 0 when building an empty (unsorted) sort order
  3. Add at least one sort field if a non-zero order ID is intended
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at api/src/main/java/org/apache/iceberg/SortOrder.java:272 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at api/src/main/java/org/apache/iceberg/SortOrder.java:272

    }

    Builder addSortField(
        Transform<?, ?> transform, int sourceId, SortDirection direction, NullOrder nullOrder) {
      SortField sortField = new SortField(transform, sourceId, direction, nullOrder);
      fields.add(sortField);
      return this;
    }

    public SortOrder build() {
      SortOrder sortOrder = buildUnchecked();
      checkCompatibility(sortOrder, schema);
      return sortOrder;
    }

    SortOrder buildUnchecked() {
      if (fields.isEmpty()) {
        if (orderId != null && orderId != 0) {
          throw new IllegalArgumentException("Unsorted order ID must be 0");
        }
        return SortOrder.unsorted();
      }

      if (orderId != null && orderId == 0) {
        throw new IllegalArgumentException("Sort order ID 0 is reserved for unsorted order");
      }

      // default ID to 1 as 0 is reserved for unsorted order
      int actualOrderId = orderId != null ? orderId : 1;
      return new SortOrder(schema, actualOrderId, fields);
    }

    private Transform<?, ?> toTransform(BoundTerm<?> term) {
      if (term instanceof BoundReference) {
        return Transforms.identity(term.type());
      } else if (term instanceof BoundTransform) {
        return ((BoundTransform<?, ?>) term).transform();

View on GitHub (pinned to 86d9c8fc54)