apache/druid · error · org.apache.druid.java.util.common.IAE

Cannot create query type helper from invalid type [%s]

Error message

Cannot create query type helper from invalid type [%s]

What it means

CardinalityAggregatorColumnSelectorStrategyFactory can only produce column selector strategies for numeric column types (LONG, FLOAT, DOUBLE). When a column's capabilities report any other type (e.g. a complex/serialized type the factory does not handle), it throws this IllegalArgumentException during query tooling setup. It indicates the cardinality aggregator was pointed at a column type it cannot process.

Source

Thrown at processing/src/main/java/org/apache/druid/query/aggregation/cardinality/types/CardinalityAggregatorColumnSelectorStrategyFactory.java:47

{
  @Override
  public CardinalityAggregatorColumnSelectorStrategy makeColumnSelectorStrategy(
      ColumnCapabilities capabilities,
      ColumnValueSelector selector,
      String dimension
  )
  {
    switch (capabilities.getType()) {
      case STRING:
        return new StringCardinalityAggregatorColumnSelectorStrategy();
      case LONG:
        return new LongCardinalityAggregatorColumnSelectorStrategy();
      case FLOAT:
        return new FloatCardinalityAggregatorColumnSelectorStrategy();
      case DOUBLE:
        return new DoubleCardinalityAggregatorColumnSelectorStrategy();
      default:
        throw new IAE("Cannot create query type helper from invalid type [%s]", capabilities.asTypeString());
    }
  }

  @Override
  public boolean supportsComplexTypes()
  {
    return false;
  }
}

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Check the actual column type of the aggregator field (via /druid/v2/datasources/{ds}/getters or segment metadata) and ensure it is LONG, FLOAT, or DOUBLE.
  2. If the column is a string and you want distinct counts, use the string-typed cardinality path or convert the column (e.g. ingest a numeric expression).
  3. If the column is a complex aggregator output, use the matching aggregator (e.g. hyperUnique/cardinality on its raw input) instead of stacking cardinality over it.
  4. Upgrade Druid if the column type is newer than your version's supported strategy set.

Example fix

// before
{"type":"cardinality","fields":["complex_metric"]}
// after
{"type":"cardinality","fields":["numeric_dim"]}
Defensive patterns

Strategy: validation

Validate before calling

ColumnCapabilities caps = selector.getCapabilities(column);
if (caps.getType() != ValueType.LONG && caps.getType() != ValueType.FLOAT && caps.getType() != ValueType.DOUBLE) {
  throw new IllegalArgumentException("cardinality supports only numeric columns, got: " + caps.asTypeString());
}

Type guard

boolean isNumericColumn(ColumnCapabilities c) {
  return c != null && (c.getType() == ValueType.LONG || c.getType() == ValueType.FLOAT || c.getType() == ValueType.DOUBLE);
}

Try / catch

try {
  strategy = factory.makeColumnSelectorStrategy(caps, selector);
} catch (IllegalArgumentException e) {
  if (e.getMessage().startsWith("Cannot create query type helper")) {
    throw new QueryPlanningException("Cardinality requires a numeric column; got " + caps.asTypeString());
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling makeColumnSelectorStrategy with ColumnValueSelectorCapabilities whose type is not LONG, FLOAT, or DOUBLE — typically when the cardinality aggregator's field resolves to a complex, STRING, or ARRAY-typed column handled by an unhandled switch default branch.

Common situations: Running a cardinality (approximate distinct count) query against a complex metric column (e.g. hyperUnique on a nested/complex column), a schema mismatch after ingestion changes, or a new column type added upstream that the factory does not know about.

Related errors


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