apache/druid · error · IllegalArgumentException
Cannot operate on a dimension with no dictionary
Error message
Cannot operate on a dimension with no dictionary
What it means
BaseTopNAlgorithm's BaseArrayProvider allocates arrays sized by the dimension's value cardinality. A negative cardinality means the DimensionSelector has no dictionary (cannot enumerate distinct values), so Druid throws IAE("Cannot operate on a dimension with no dictionary") instead of allocating against an undefined size.
Source
Thrown at processing/src/main/java/org/apache/druid/query/topn/BaseTopNAlgorithm.java:268
private final TopNCursorInspector cursorInspector;
public BaseArrayProvider(
DimensionSelector dimSelector,
TopNQuery query,
TopNCursorInspector cursorInspector
)
{
this.idLookup = dimSelector.idLookup();
this.query = query;
this.cursorInspector = cursorInspector;
previousStop = null;
ignoreAfterThreshold = false;
ignoreFirstN = 0;
keepOnlyN = dimSelector.getValueCardinality();
if (keepOnlyN < 0) {
throw new IAE("Cannot operate on a dimension with no dictionary");
}
}
@Override
public void skipTo(String previousStop)
{
ColumnCapabilities capabilities = cursorInspector.getColumnInspector()
.getColumnCapabilities(query.getDimensionSpec().getDimension());
if (capabilities != null && capabilities.areDictionaryValuesSorted().isTrue()) {
this.previousStop = previousStop;
}
}
@Override
public void ignoreAfterThreshold()
{
ignoreAfterThreshold = true;
}View on GitHub (pinned to 9b90983fd2)
Solutions
- Query a dictionary-encoded string dimension, or add it at ingestion time
- Replace topN with groupBy + limitSpec, which handles non-dictionary dimensions
- Remove the expression/extract dimension spec, or materialize it as a real column
- Check the segment metadata (GET /druid/v2/datasources/.../candidates) to confirm the column has a dictionary
Example fix
// before
{ "queryType": "topN", "dimension": { "type": "default", "dimension": "someNumericCol" } }
// after
{ "queryType": "groupBy", "dimensions": ["someNumericCol"], "limitSpec": { "type": "default", "limit": 10 } } Defensive patterns
Strategy: fallback
Validate before calling
boolean safe = selector != null && selector.getValueCardinality() >= 0;
Type guard
static boolean supportsTopNArray(DimensionSelector s) { return s != null && s.getValueCardinality() >= 0; } Try / catch
try { return defaultTopNRun(query); }
catch (IllegalArgumentException e) {
if (e.getMessage().contains("no dictionary")) { return groupByFallback(query); }
throw e;
} Prevention
- TopN only on dictionary-encoded string dimensions
- Check segment metadata for dictionary availability
- Materialize expression dimensions at ingestion
When it happens
Trigger: TopN query with the default (dictionary-based) topN algorithm on a dimension whose selector lacks a value dictionary: expression dimensions, columns without dictionary encoding, or selectors returning cardinality < 0.
Common situations: TopN on __time or numeric columns, querying non-string metric columns as dimensions, expression virtual columns, segments written by older ingestion that lacked dictionary encoding.
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
- Can't find the topN metric
- Cannot operate on a dimension with unknown cardinality
- 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/1d22bd7910721140.
Report an issue: GitHub.