apache/druid · error · IllegalStateException

Unable to handle complex type[%s]

Error message

Unable to handle complex type[%s]

What it means

When IncrementalIndex sets up column capabilities for an aggregator of COMPLEX ValueType, it looks up a ComplexMetricSerde by the complex type name. If none is registered (ComplexMetrics.getSerdeForType returns null) the index cannot serialize/handle that complex type and throws this ISE.

Source

Thrown at processing/src/main/java/org/apache/druid/segment/incremental/IncrementalIndex.java:1034

    private final int index;
    private final String name;
    private final String type;
    private final ColumnCapabilities capabilities;

    public MetricDesc(int index, AggregatorFactory factory)
    {
      this.index = index;
      this.name = factory.getName();

      ColumnType valueType = factory.getIntermediateType();

      if (valueType.isNumeric()) {
        capabilities = ColumnCapabilitiesImpl.createSimpleNumericColumnCapabilities(valueType);
        this.type = valueType.toString();
      } else if (valueType.is(ValueType.COMPLEX)) {
        ComplexMetricSerde serde = ComplexMetrics.getSerdeForType(valueType.getComplexTypeName());
        if (serde == null) {
          throw new ISE("Unable to handle complex type[%s]", valueType);
        }
        this.type = serde.getTypeName();
        // The serde's type name represents the canonical storage type (e.g., "HLLSketch"),
        // while the aggregator's intermediate type may be more specific (e.g., "HLLSketchBuild").
        // Using the serde's type ensures that segment metadata queries return consistent types
        // across realtime (IncrementalIndex) and historical (QueryableIndex) segments.
        // See https://github.com/apache/druid/issues/14315.
        capabilities = ColumnCapabilitiesImpl.createDefault()
                                             .setType(ColumnType.ofComplex(serde.getTypeName()))
                                             .setHasNulls(ColumnCapabilities.Capable.TRUE);
      } else {
        // if we need to handle non-numeric and non-complex types (e.g. strings, arrays) it should be done here
        // and we should determine the appropriate ColumnCapabilities
        throw new ISE("Unable to handle type[%s] for AggregatorFactory[%s]", valueType, factory.getClass());
      }
    }

    public int getIndex()

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Load the extension providing the serde (e.g. druid-datasketches) via druid.extensions.loadList on the server running the task
  2. Verify ComplexMetrics registry contains the type (check extension was bundled into the task classpath)
  3. Correct the aggregator/typeName spelling so it matches a registered serde

Example fix

// before (server not loading sketch extension)
"druid.extensions.loadList": ["druid-kafka-indexing-service"]
// after
"druid.extensions.loadList": ["druid-kafka-indexing-service", "druid-datasketches"]
Defensive patterns

Strategy: validation

Validate before calling

if (ComplexMetrics.getSerdeForType(typeName) == null) {
  throw new IllegalStateException("No serde for " + typeName + "; check druid.extensions.loadList");
}

Try / catch

try { initIndex(); } catch (ISE e) { if (e.getMessage().startsWith("Unable to handle complex type")) { /* load missing extension */ } throw e; }

Prevention

When it happens

Trigger: Creating an IncrementalIndex with an AggregatorFactory whose required type is COMPLEX (e.g. sketch aggregators) while no serde is registered for that complex type name, typically because the extension providing the serde is not loaded.

Common situations: Using datasketches/HLL/streaming-aggregation aggregators without loading the corresponding Druid extension on the ingestion/peon server; typo'd complex type names.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


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