apache/druid · error · IllegalStateException
Can't find the topN metric
Error message
Can't find the topN metric
What it means
AggregateTopNMetricFirstAlgorithm runs topN for a single metric by condensing the query's aggregators/postAggregators down to those the topN metric depends on. If after condensing both lists are empty, the requested topN metric is not produced by any aggregator, so Druid throws ISE("Can't find the topN metric").
Source
Thrown at processing/src/main/java/org/apache/druid/query/topn/AggregateTopNMetricFirstAlgorithm.java:83
public TopNParams makeInitParams(ColumnSelectorPlus selectorPlus, Cursor cursor, CursorGranularizer granularizer)
{
return new TopNParams(selectorPlus, cursor, granularizer, Integer.MAX_VALUE);
}
@Override
public void run(
TopNParams params,
TopNResultBuilder resultBuilder,
int[] ints,
@Nullable TopNQueryMetrics queryMetrics
)
{
final String metric = query.getTopNMetricSpec().getMetricName(query.getDimensionSpec());
Pair<List<AggregatorFactory>, List<PostAggregator>> condensedAggPostAggPair =
AggregatorUtil.condensedAggregators(query.getAggregatorSpecs(), query.getPostAggregatorSpecs(), metric);
if (condensedAggPostAggPair.lhs.isEmpty() && condensedAggPostAggPair.rhs.isEmpty()) {
throw new ISE("Can't find the topN metric");
}
// Run topN for only a single metric
TopNQuery singleMetricQuery = new TopNQueryBuilder(query)
.aggregators(condensedAggPostAggPair.lhs)
.postAggregators(condensedAggPostAggPair.rhs)
.build();
final TopNResultBuilder singleMetricResultBuilder = BaseTopNAlgorithm.makeResultBuilder(params, singleMetricQuery);
PooledTopNAlgorithm singleMetricAlgo = new PooledTopNAlgorithm(singleMetricQuery, cursorInspector, bufferPool);
PooledTopNAlgorithm.PooledTopNParams singleMetricParam = null;
int[] dimValSelector;
try {
singleMetricParam = singleMetricAlgo.makeInitParams(params.getSelectorPlus(), params.getCursor(), params.getGranularizer());
singleMetricAlgo.run(
singleMetricParam,
singleMetricResultBuilder,
null,
null // Don't collect metrics during the preparation run.View on GitHub (pinned to 9b90983fd2)
Solutions
- Make the topN metric name exactly match an aggregator output or post-aggregator name in the query
- Add the missing aggregator/postAggregator to the query so it produces the metric
- Simplify to a direct aggregator output metric (e.g. use the base 'metric' the post-agg derives from)
- Print AggregatorUtil.condensedAggregators inputs/outputs when debugging programmatic query builders
Example fix
// before
new TopNQueryBuilder().metric("clickt").aggregators(new CountAggregatorFactory("count"))...
// after
new TopNQueryBuilder().metric("count").aggregators(new CountAggregatorFactory("count"))... Defensive patterns
Strategy: validation
Validate before calling
Set<String> produced = new HashSet<>(); query.getAggregatorSpecs().forEach(a -> produced.add(a.getName())); query.getPostAggregatorSpecs().forEach(p -> produced.add(p.getName())); boolean safe = produced.contains(query.getTopNMetricSpec().getMetricName(query.getDimensionSpec()));
Type guard
static boolean metricIsProduced(TopNQuery q) {
String m = q.getTopNMetricSpec().getMetricName(q.getDimensionSpec());
return q.getAggregatorSpecs().stream().anyMatch(a -> a.getName().equals(m))
|| q.getPostAggregatorSpecs().stream().anyMatch(p -> p.getName().equals(m));
} Try / catch
try { return algo.run(params, builder, op); }
catch (IllegalStateException e) { if (e.getMessage().equals("Can't find the topN metric")) { throw new InvalidQueryException(e); } throw e; } Prevention
- Validate topN metric names against aggregators before submitting
- Avoid referencing post-aggregators whose inputs were pruned
- Keep query builder helpers in sync with schema changes
When it happens
Trigger: A TopNQuery whose topNMetricSpec.getMetricName() refers to a name absent from both aggregatorSpecs and postAggregatorSpecs — e.g. a typo in the metric name, or a metric produced only by a filtered/aggregator chain that condensing removed.
Common situations: Typos in orderBySpec metric names, referencing a post-aggregator output whose inputs were pruned, programmatically built queries reusing stale metric names after schema changes.
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 operate on a dimension with unknown cardinality
- Cannot operate on a dimension with no dictionary
- Only DimensionSelectors which support idLookup() are support
- Cannot operate on a dimension with unknown cardinality
- Unknown type[%s] for metric[%s]
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/c8d64a0d5c0905f4.
Report an issue: GitHub.