apache/druid · error · IllegalStateException
Unable to handle type
Error message
Unable to handle type[%s] for AggregatorFactory[%s]
What it means
IncrementalIndex's MetricDesc/MetricHolder capabilities logic only handles numeric and COMPLEX ValueTypes; anything else (e.g. STRING, arrays) for an AggregatorFactory's required type is rejected with this ISE. It marks an unsupported combination of aggregator output type and index capability handling.
Solutions
- Change the aggregator so its output type is numeric or a registered complex type
- For string outputs, use a dimension plus query-time aggregation instead of an ingestion-time metric
- Patch/extend IncrementalIndex capability handling if this is your own custom aggregator type
Example fix
// before: custom aggregator with typeName "string"
public String getTypeName() { return "string"; }
// after: return a complex or numeric type
public String getTypeName() { return "long"; } Defensive patterns
Strategy: validation
Validate before calling
String t = factory.getTypeName();
if (!isNumeric(t) && !isComplex(t)) throw new IllegalArgumentException("Bad aggregator type: " + t); Try / catch
try { index.add(row); } catch (ISE e) { if (e.getMessage().contains("Unable to handle type")) { /* fix aggregator */ } throw e; } Prevention
- Audit custom AggregatorFactory getTypeName values
- Restrict metricsSpec to known aggregator types
When it happens
Trigger: Constructing an IncrementalIndex with an AggregatorFactory whose getTypeName()/required type resolves to a non-numeric, non-complex ValueType (STRING or ARRAY), e.g. a custom aggregator returning strings or a misconfigured spec.
Common situations: Custom AggregatorFactory implementations declaring string/array intermediate types; spec errors where a dimension-style aggregator is used in metricsSpec; upgrading Druid where new ValueTypes (arrays) exist but index support is absent.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Could not convert value
- Attempt to add row to swapped-out sink for segment
- attempt to get boolean[] null vector from string[] only…
- attempt to get double[] from string[] only scalar binding
- attempt to get long[] from string[] only scalar binding
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/cf8f5b6a2f4afd92.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/segment/incremental/IncrementalIndex.java:1048
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()
{
return index;
}
public String getName()
{
return name;
}
public String getType()
{
return type;
}
View on GitHub (pinned to 9b90983fd2)