apache/druid · error · UnsupportedOperationException
Only DimensionSelectors which support idLookup() are support
Error message
Only DimensionSelectors which support idLookup() are supported yet
What it means
When resuming a topN scan after skipTo(previousStop), BaseTopNAlgorithm needs to translate the previous stop value into a dictionary id via the selector's idLookup(). If the DimensionSelector does not support idLookup (null), Druid throws UnsupportedOperationException because position-based resume is impossible.
Source
Thrown at processing/src/main/java/org/apache/druid/query/topn/BaseTopNAlgorithm.java:307
public void ignoreFirstN(int n)
{
ignoreFirstN = n;
}
@Override
public void keepOnlyN(int n)
{
keepOnlyN = n;
}
@VisibleForTesting
public Pair<Integer, Integer> computeStartEnd(int cardinality)
{
int startIndex = ignoreFirstN;
if (previousStop != null) {
if (idLookup == null) {
throw new UnsupportedOperationException("Only DimensionSelectors which support idLookup() are supported yet");
}
int lookupId = idLookup.lookupId(previousStop) + 1;
if (lookupId < 0) {
lookupId *= -1;
}
if (lookupId > ignoreFirstN + keepOnlyN) {
startIndex = ignoreFirstN + keepOnlyN;
} else {
startIndex = Math.max(lookupId, startIndex);
}
}
int endIndex = Math.min(ignoreFirstN + keepOnlyN, cardinality);
final TopNOptimizationInspector topNOptimizationInspector = cursorInspector.getOptimizationInspector();
if (ignoreAfterThreshold &&
query.getDimensionsFilter() == null &&
topNOptimizationInspector != null &&View on GitHub (pinned to 9b90983fd2)
Solutions
- Use a plain string dimension with dictionary encoding for topN queries
- Remove the previousStop/time-order pagination options (run the query in one pass)
- Pre-materialize lookup/extraction results as a real dimension at ingestion
- Fall back to groupBy+limit which doesn't rely on idLookup
Example fix
// before
{ "dimension": { "type": "extraction", "dimension": "x", "extractionFn": {"type":"registeredLookup"} } }
// after
{ "dimension": "x_materialized" } // lookup applied at ingestion Defensive patterns
Strategy: fallback
Validate before calling
boolean safe = selector.supportsLookupNameFn() && previousStop == null || selector.idLookup() != null;
Type guard
static boolean supportsIdLookup(DimensionSelector s) { return s != null && s.idLookup() != null; } Try / catch
try { return pagedTopNRun(query); }
catch (UnsupportedOperationException e) {
if (e.getMessage().contains("idLookup")) { return singlePassTopNRun(query); }
throw e;
} Prevention
- Avoid skipTo/pagination on extraction dimensionSpecs
- Use plain dictionary-encoded dimensions for paged topN
- Materialize lookups before querying
When it happens
Trigger: TopN scan with ignoreFirstN/keepOnlyN pagination hitting skipTo(previousStop) against a selector without idLookup support — e.g. expression/extraction dimensions or non-dictionary selectors combined with a non-null previousStop.
Common situations: TopN queries with time-order/pagination options on expression dimensions, cursor reuse across custom selectors lacking idLookup, dimensionSpecs (lookup/extraction) whose selectors don't implement lookup by id.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Cannot operate on a dimension with unknown cardinality
- Not implemented
- Not implemented
- Not implemented
- Not implemented
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/91a5b64b8ce0424d.
Report an issue: GitHub.