apache/iceberg · error · IllegalArgumentException

Sort order ID 0 is reserved for unsorted order

Error message

Sort order ID 0 is reserved for unsorted order

What it means

Consistency check in SortOrder.Builder.buildUnchecked: the builder has sort fields but an explicit orderId of 0. Order ID 0 is reserved for the unsorted order in the Iceberg spec, so a populated sort order cannot carry it; the build is rejected before the SortOrder is created.

Solutions

  1. Let the builder assign a fresh non-zero order ID by not calling orderId()
  2. Supply a positive unique order ID obtained from the table metadata
  3. Upgrade the sort order instead of rebuilding with ID 0
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at api/src/main/java/org/apache/iceberg/SortOrder.java:278 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/a194915837c646b5. Report an issue: GitHub.

Appendix: source

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

      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();
      } else {
        throw new ValidationException(
            "Invalid term: %s, expected either a bound reference or transform", term);
      }
    }
  }

View on GitHub (pinned to 86d9c8fc54)