apache/druid · error · IllegalArgumentException
Cannot order by a non-numeric aggregator[%s]
Error message
Cannot order by a non-numeric aggregator[%s]
What it means
Thrown by bufferComparatorWithAggregators when an ORDER BY / limit column maps to an aggregator whose output value type is not numeric (e.g. STRING or COMPLEX). The group-by v2 engine's in-memory buffer comparator can only compare aggregator slots numerically, so a non-numeric aggregator in the ordering spec cannot be supported and the query is rejected at comparator construction time.
Source
Thrown at processing/src/main/java/org/apache/druid/query/groupby/epinephelinae/GrouperBufferComparatorUtils.java:158
for (OrderByColumnSpec orderSpec : limitSpec.getColumns()) {
needsReverse = orderSpec.getDirection() != OrderByColumnSpec.Direction.ASCENDING;
int dimIndex = OrderByColumnSpec.getDimIndexForOrderBy(orderSpec, dimensions);
if (dimIndex >= 0) {
comparators.add(dimComparators[dimIndex]);
orderByIndices.add(dimIndex);
needsReverses.add(needsReverse);
} else {
int aggIndex = OrderByColumnSpec.getAggIndexForOrderBy(orderSpec, Arrays.asList(aggregatorFactories));
if (aggIndex >= 0) {
final StringComparator stringComparator = orderSpec.getDimensionComparator();
final ColumnType valueType = aggregatorFactories[aggIndex].getIntermediateType();
// Aggregators start after dimensions
final int aggOffset = keySize + aggregatorOffsets[aggIndex];
aggCount++;
if (!valueType.isNumeric()) {
throw new IAE("Cannot order by a non-numeric aggregator[%s]", orderSpec);
}
comparators.add(
makeNullHandlingBufferComparatorForNumericData(
aggOffset,
makeNumericBufferComparator(valueType, aggOffset, true, stringComparator)
)
);
needsReverses.add(needsReverse);
}
}
}
for (int i = 0; i < dimCount; i++) {
if (!orderByIndices.contains(i)) {
comparators.add(dimComparators[i]);
needsReverses.add(false); // default to Ascending order if dim is not in an orderby spec
}View on GitHub (pinned to 9b90983fd2)
Solutions
- Order by a numeric aggregator output instead, or add a numeric aggregator (e.g. longSum/count) computed from the same column and order by that.
- If ordering by a string value is required, remove the sort column from the limit spec and sort client-side, or use a post-aggregator that yields a number.
- Cast/convert the string aggregator to numeric where semantically valid (e.g. parse the string to a number in a downstream step or via a numeric aggregator at ingestion).
Example fix
// before: orderByColumnSpecs: ["stringFirst(user)"] with aggregator stringFirst("user")
// after
{"type":"longSum","name":"userCount","fieldName":"events"}
// order by "userCount" instead of the string aggregator output Defensive patterns
Strategy: validation
Validate before calling
for (String col : limitSpec.getColumns()) {
String type = resolveOutputType(query, col.getDimension());
if (type != null && !NUMERIC_TYPES.contains(type)) {
throw new IllegalArgumentException("Order-by column '" + col.getDimension() + "' has non-numeric aggregator type " + type);
}
} Prevention
- Only order by numeric aggregator/post-aggregator outputs in groupBy queries
- Check aggregator outputType before wiring it into the limit spec
- Prefer explicit numeric aggregators (longSum/doubleSum) for sort keys
When it happens
Trigger: Building a Grouper buffer comparator with an OrderByColumnSpec whose column resolves to a non-numeric aggregator output type (aggregatorOffset lookup succeeds but valueType.isNumeric() is false), e.g. ordering by a 'stringFirst'/'stringLast'/filtered-string or sketch aggregator output in a groupBy query with sort/limit columns.
Common situations: Users add topN/limit orderBy on a stringFirst, stringLast, earliest/latest-by (string output), or HLL sketch aggregator; queries migrated from other engines where ordering by strings is allowed; auto-generated dashboards sorting by whatever column the user clicked.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Unknown column in order clause[%s]
- Invalid operation for AveragerFactoryWrapper.
- Must have a valid, non-null aggregator name
- Parameter fieldName must be specified
- Not implemented
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/fd62a324d2ffac25.
Report an issue: GitHub.