apache/druid · error · IllegalStateException
Unknown column in order clause[%s]
Error message
Unknown column in order clause[%s]
What it means
DefaultLimitSpec.getOrderByType resolves the output type of a column in the ORDER BY / limit clause by looking it up among the query's aggregators, post-aggregators, and dimension specs. If the ordering column matches none of them, an IllegalStateException is thrown — meaning the limit spec references a column the query does not actually produce.
Source
Thrown at processing/src/main/java/org/apache/druid/query/groupby/orderby/DefaultLimitSpec.java:294
}
// Finally, apply offset after sorting and limiting.
if (isOffset()) {
return results -> sortAndLimitFn.apply(results).skip(offset);
} else {
return sortAndLimitFn;
}
}
private ColumnType getOrderByType(final OrderByColumnSpec columnSpec, final List<DimensionSpec> dimensions)
{
for (DimensionSpec dimSpec : dimensions) {
if (columnSpec.getDimension().equals(dimSpec.getOutputName())) {
return dimSpec.getOutputType();
}
}
throw new ISE("Unknown column in order clause[%s]", columnSpec);
}
@Override
public LimitSpec filterColumns(Set<String> names)
{
return new DefaultLimitSpec(
columns.stream().filter(c -> names.contains(c.getDimension())).collect(Collectors.toList()),
offset,
limit
);
}
/**
* Returns a new DefaultLimitSpec identical to this one except for one difference: an offset parameter, if any, will
* be removed and added to the limit. This is designed for passing down queries to lower levels of the stack. Only
* the highest level should apply the offset parameter, and any pushed-down limits must be increased to accommodate
* the offset.
*/View on GitHub (pinned to 9b90983fd2)
Solutions
- Make the orderBy column name exactly match a dimension outputName, aggregator, or post-aggregator in the same query spec.
- Add the referenced column as a dimension/aggregator or remove it from the limit spec.
- If sorting should happen after an outer query, restructure with a nested query where each layer's limit spec references only its own outputs.
Example fix
// before
"limitSpec":{"type":"default","columns":[{"dimension":"user_name"}]}
// but dimension is {"dimension":"user","outputName":"user"}
// after
"limitSpec":{"type":"default","columns":[{"dimension":"user"}]} Defensive patterns
Strategy: validation
Validate before calling
Set<String> outputs = new HashSet<>();
dimensions.forEach(d -> outputs.add(d.getOutputName()));
aggregators.forEach(a -> outputs.add(a.getName()));
postAggregators.forEach(p -> outputs.add(p.getName()));
for (OrderByColumnSpec c : limitSpec.getColumns()) {
if (!outputs.contains(c.getDimension())) throw new IllegalArgumentException("Unknown order-by column: " + c.getDimension());
} Try / catch
try {
return engine.plan(query);
} catch (IllegalStateException e) {
if (e.getMessage() != null && e.getMessage().contains("Unknown column in order clause")) {
throw new QueryValidationException(e.getMessage(), e);
}
throw e;
} Prevention
- Validate limitSpec columns against query outputs before submitting
- Use exact outputName (not input fieldName) in order-by specs
- When renaming dimension outputName, update all limit specs referencing it
- Catch ISE at plan time and translate to a user-facing validation error
When it happens
Trigger: A DefaultLimitSpec (limit/orderBy in a groupBy or topN query) contains an OrderByColumnSpec whose name matches no dimension outputName, aggregator name, or post-aggregator name; getOrderByType is called during planning (e.g. via columnType).
Common situations: Typos in orderBy column names; dashboard/UI sending sort keys for columns removed from the query; renaming a dimension outputName without updating the limit spec; nested queries where the sort column only exists in the inner query.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Cannot order by a non-numeric aggregator[%s]
- Could not find the dimension spec for ordering column %s
- Invalid maxLoadFactor[%f], must be < 1.0
- Invalid maxLoadFactor[%f], must be < 1.0
- Vectorized groupBys on multi-value dictionary-encoded dimens
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/6198c610ee5ccc40.
Report an issue: GitHub.