apache/druid · error · IllegalStateException
Could not find the dimension spec for ordering column %s
Error message
Could not find the dimension spec for ordering column %s
What it means
DefaultLimitSpec.makeComparator builds a comparator chain for the limit spec. When an ordering column is a dimension (found in dimensionsMap), it filters the dimensions list for the spec with the matching outputName; if dimensionsMap contains the name but the dimensions stream yields no spec (inconsistent map/list state), an IllegalStateException is thrown. This is an internal consistency failure between the derived map and the dimension spec list.
Source
Thrown at processing/src/main/java/org/apache/druid/query/groupby/orderby/DefaultLimitSpec.java:392
for (OrderByColumnSpec columnSpec : columns) {
String columnName = columnSpec.getDimension();
Ordering<ResultRow> nextOrdering = null;
final int columnIndex = rowSignature.indexOf(columnName);
if (columnIndex >= 0) {
if (postAggregatorsMap.containsKey(columnName)) {
//noinspection unchecked
nextOrdering = metricOrdering(columnIndex, postAggregatorsMap.get(columnName).getComparator());
} else if (aggregatorsMap.containsKey(columnName)) {
//noinspection unchecked
nextOrdering = metricOrdering(columnIndex, aggregatorsMap.get(columnName).getComparator());
} else if (dimensionsMap.containsKey(columnName)) {
Optional<DimensionSpec> dimensionSpec = dimensions.stream()
.filter(ds -> ds.getOutputName().equals(columnName))
.findFirst();
if (!dimensionSpec.isPresent()) {
throw new ISE("Could not find the dimension spec for ordering column %s", columnName);
}
nextOrdering = dimensionOrdering(
columnIndex,
dimensionSpec.get().getOutputType(),
columnSpec.getDimensionComparator()
);
}
}
if (nextOrdering == null) {
throw new ISE("Unknown column in order clause[%s]", columnSpec);
}
if (columnSpec.getDirection() == OrderByColumnSpec.Direction.DESCENDING) {
nextOrdering = nextOrdering.reverse();
}
ordering = ordering == null ? nextOrdering : ordering.compound(nextOrdering);View on GitHub (pinned to 9b90983fd2)
Solutions
- Ensure each ordering column appears in exactly one dimension spec with a unique outputName.
- Rebuild the query spec so dimensionsMap and dimensions are derived from the same list (use the provided builder helpers rather than hand-rolled maps).
- If this arises during normal Druid usage (not custom code), it indicates a bug — collect the query spec and file an issue.
Example fix
// before: two dimensions with same outputName "user" // after: deduplicate List<DimensionSpec> distinct = dims.stream().distinct().collect(Collectors.toList()); return DefaultLimitSpec.sortingComparatorWithAggregators(orderings, distinct, aggregators);
Defensive patterns
Strategy: validation
Validate before calling
long distinctNames = dimensions.stream().map(DimensionSpec::getOutputName).distinct().count();
if (distinctNames != dimensions.size()) {
throw new IllegalArgumentException("Duplicate dimension outputName detected");
} Prevention
- Keep dimension outputNames unique across the query spec
- Always derive dimension/aggregator maps from the same list used for the limit spec
- Avoid hand-building the map/list inputs to sortingComparatorWithAggregators
When it happens
Trigger: makeComparator encounters columnName present in dimensionsMap but dimensions.stream().filter(ds -> ds.getOutputName().equals(columnName)).findFirst() is empty — e.g. duplicate dimension outputNames colliding on map keys while the filter unexpectedly fails, or API misuse producing divergent map/list inputs.
Common situations: Programmatic construction of DefaultLimitSpec.sortingComparatorWithAggregators with mismatched dimensions/aggregators collections; duplicate output names; engine-internal state divergence after query rewrite.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Unknown column in order clause[%s]
- interval %s, bucketId %s mismatched shard specs: %s and %s
- Unexpected state: Two versions([%s], [%s]) for the same inte
- Cannot order by a non-numeric aggregator[%s]
- Cannot apply limit[%d] with offset[%d] due to overflow
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/df37fe04fa9a9975.
Report an issue: GitHub.