apache/druid · error · UnsupportedOperationException
Cannot operate on a dimension with no dictionary
Error message
Cannot operate on a dimension with no dictionary
What it means
PooledTopNAlgorithm.makeInitParams requires a dictionary-encoded dimension selector; getValueCardinality() must return >= 0. A negative cardinality means the dimension has no dictionary (e.g. a string dimension backed by a non-dictionary or an uninitialized/foreign storage adapter), so the algorithm cannot allocate its int[cardinality] positions array. Druid throws UnsupportedOperationException because topN over an undictionary-able dimension is not supported in the pooled algorithm.
Source
Thrown at processing/src/main/java/org/apache/druid/query/topn/PooledTopNAlgorithm.java:234
public PooledTopNAlgorithm(
TopNQuery query,
TopNCursorInspector cursorInspector,
NonBlockingPool<ByteBuffer> bufferPool
)
{
super(cursorInspector);
this.query = query;
this.bufferPool = bufferPool;
}
@Override
public PooledTopNParams makeInitParams(ColumnSelectorPlus selectorPlus, Cursor cursor, CursorGranularizer granularizer)
{
final DimensionSelector dimSelector = (DimensionSelector) selectorPlus.getSelector();
final int cardinality = dimSelector.getValueCardinality();
if (cardinality < 0) {
throw new UnsupportedOperationException("Cannot operate on a dimension with no dictionary");
}
final TopNMetricSpecBuilder<int[]> arrayProvider = new BaseArrayProvider<>(dimSelector, query, cursorInspector)
{
private final int[] positions = new int[cardinality];
@Override
public int[] build()
{
Pair<Integer, Integer> startEnd = computeStartEnd(cardinality);
Arrays.fill(positions, 0, startEnd.lhs, SKIP_POSITION_VALUE);
Arrays.fill(positions, startEnd.lhs, startEnd.rhs, INIT_POSITION_VALUE);
Arrays.fill(positions, startEnd.rhs, positions.length, SKIP_POSITION_VALUE);
return positions;
}
};View on GitHub (pinned to 9b90983fd2)
Solutions
- Use a dictionary-encoded string column as the topN dimension
- Enable/verify dictionary encoding for the column at ingestion (string columns are dictionary-encoded by default)
- Rewrite the query as a groupBy if the dimension cannot have a dictionary or cardinality is unknown
- If using an expression dimension, ensure it produces dictionary-encoded values or switch to groupBy
Example fix
// before topN(dimension: "concat(country, '-x')") // expression dim with no dictionary // after groupBy(dimension: "concat(country, '-x')") // groupBy supports unknown cardinality
Defensive patterns
Strategy: validation
Validate before calling
DimensionSelector selector = (DimensionSelector) selectorPlus.getSelector();
if (selector.getValueCardinality() < 0) {
// fall back to groupBy or choose a dictionary-encoded dimension
} Type guard
boolean hasDictionary(DimensionSelector selector) {
return selector.getValueCardinality() >= 0;
} Try / catch
try {
return topNEngine.query(...);
} catch (UnsupportedOperationException e) {
if (e.getMessage().contains("no dictionary")) { /* run groupBy instead */ }
throw e;
} Prevention
- Prefer dictionary-encoded string columns for topN dimensions
- Use groupBy for expression/virtual dimensions or unknown cardinality
- Check cardinality (ColumnHolder/Column capabilities) before choosing topN at query-build time
When it happens
Trigger: Running a topN query where the 'dimension' resolves to a selector whose getValueCardinality() returns -1 — typically a non-dictionary-encoded column, a virtual/expression dimension without dictionary support, or a segment whose string dictionary is unavailable.
Common situations: TopN on an expression/virtual column lacking a dictionary; querying segments written with dictionary-less string columns; misuse of topN where groupBy v2 should be used for high-cardinality or unencoded dimensions.
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
- Unknown type[%s] for metric[%s]
- Null cursor factory found. Probably trying to issue a query
- Query type '%s' does not support returning results as arrays
- Can't find the topN metric
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/007fdeeb70f504ef.
Report an issue: GitHub.