apache/druid · error · UnsupportedOperationException

Cannot operate on a dimension with unknown cardinality

Error message

Cannot operate on a dimension with unknown cardinality

What it means

HeapBasedTopNAlgorithm.makeDimValSelector builds per-dimension-value arrays and therefore requires the dimension's cardinality to be known. If params.getCardinality() < 0 (selector has no dictionary), Druid throws UnsupportedOperationException("Cannot operate on a dimension with unknown cardinality").

Source

Thrown at processing/src/main/java/org/apache/druid/query/topn/HeapBasedTopNAlgorithm.java:67

  public TopNParams makeInitParams(
      final ColumnSelectorPlus<TopNColumnAggregatesProcessor> selectorPlus,
      final Cursor cursor,
      final CursorGranularizer granularizer
  )
  {
    return new TopNParams(
        selectorPlus,
        cursor,
        granularizer,
        Integer.MAX_VALUE
    );
  }

  @Override
  protected Aggregator[][] makeDimValSelector(TopNParams params, int numProcessed, int numToProcess)
  {
    if (params.getCardinality() < 0) {
      throw new UnsupportedOperationException("Cannot operate on a dimension with unknown cardinality");
    }
    ColumnSelectorPlus<TopNColumnAggregatesProcessor> selectorPlus = params.getSelectorPlus();
    return selectorPlus.getColumnSelectorStrategy().getRowSelector(query, params, cursorInspector);
  }

  @Override
  protected Aggregator[][] updateDimValSelector(Aggregator[][] aggregators, int numProcessed, int numToProcess)
  {
    return aggregators;
  }

  @Override
  protected TopNColumnAggregatesProcessor makeDimValAggregateStore(TopNParams params)
  {
    final ColumnSelectorPlus<TopNColumnAggregatesProcessor> selectorPlus = params.getSelectorPlus();
    return selectorPlus.getColumnSelectorStrategy();
  }

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Switch the query to groupBy with an orderBys/limitSpec — no cardinality requirement
  2. Use a dictionary-encoded string dimension (check segment metadata for the column)
  3. Materialize the expression/lookup dimension as a physical column at ingestion
  4. Choose a topN algorithm/sort combination compatible with the dimension's selector (e.g. default alphabetical)

Example fix

// before
{ "queryType": "topN", "dimension": { "type": "expression", "expression": "concat(x,'-sfx')" }, "metric": { "type": "inverted", "metric": "count" } }
// after
{ "queryType": "groupBy", "dimensions": [{ "type": "expression", "expression": "concat(x,'-sfx')" }], "limitSpec": { "type": "default", "limit": 10, "columns": [{ "dimension": "count", "direction": "descending" }] } }
Defensive patterns

Strategy: fallback

Validate before calling

int card = params.getCardinality();
boolean safe = card >= 0;

Type guard

static boolean heapTopNSafe(TopNParams p) { return p != null && p.getCardinality() >= 0; }

Try / catch

try { return heapTopNRun(query); }
catch (UnsupportedOperationException e) {
  if (e.getMessage().contains("unknown cardinality")) { return groupByWithOrderBy(query); }
  throw e;
}

Prevention

When it happens

Trigger: TopN query using the heap-based algorithm (non-dictionary-ordering metric order, e.g. inverted numeric sort) on a dimension whose DimensionSelector reports unknown cardinality — expression dimensions, non-string columns, or selectors without dictionary support.

Common situations: TopN with descending/lexicographic-inverted sort on expression or lookup-wrapped dimensions, querying columns without dictionary encoding, custom segment formats that skip dictionary building.

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


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/3db82ec59a51da76. Report an issue: GitHub.