apache/druid · error · IllegalStateException
Expected complex type with defined complexTypeName, but got
Error message
Expected complex type with defined complexTypeName, but got [%s]
What it means
ComplexFieldReader.createFromType builds a reader for a COMPLEX column, which requires a named complex type (complexTypeName) so the matching ComplexMetricSerde can be resolved. It throws ISE when the ColumnType is null, is not ValueType.COMPLEX, or is COMPLEX without a complexTypeName set.
Source
Thrown at processing/src/main/java/org/apache/druid/frame/field/ComplexFieldReader.java:66
* Format:
* <p>
* - 1 byte: {@link ComplexFieldWriter#NULL_BYTE} or {@link ComplexFieldWriter#NOT_NULL_BYTE}
* - 4 bytes: length of serialized complex value, little-endian int
* - N bytes: serialized complex value
*/
public class ComplexFieldReader implements FieldReader
{
private final ComplexMetricSerde serde;
ComplexFieldReader(final ComplexMetricSerde serde)
{
this.serde = Preconditions.checkNotNull(serde, "serde");
}
public static ComplexFieldReader createFromType(final ColumnType columnType)
{
if (columnType == null || columnType.getType() != ValueType.COMPLEX || columnType.getComplexTypeName() == null) {
throw new ISE("Expected complex type with defined complexTypeName, but got [%s]", columnType);
}
final ComplexMetricSerde serde = ComplexMetrics.getSerdeForType(columnType.getComplexTypeName());
if (serde == null) {
throw new ISE("No serde for complexTypeName[%s]", columnType.getComplexTypeName());
}
return new ComplexFieldReader(serde);
}
@Override
public ColumnValueSelector<?> makeColumnValueSelector(Memory memory, ReadableFieldPointer fieldPointer)
{
return new Selector<>(memory, fieldPointer, serde);
}
@OverrideView on GitHub (pinned to 9b90983fd2)
Solutions
- Inspect the ColumnType with ColumnType.toString()/getType() and confirm it is ValueType.COMPLEX with a non-null complexTypeName.
- Ensure the column descriptor/serialized payload actually records the complex type name (e.g. hyperUnique, quantilesDoublesSketch).
- Route non-complex columns to FieldReaders.create (which dispatches per type) instead of createFromType.
- If schema came from old data, re-ingest or upgrade segments so complex type names are present.
Example fix
// before
if (type.getType() == ValueType.COMPLEX) { reader = ComplexFieldReader.createFromType(type); }
// after
if (type != null && type.getType() == ValueType.COMPLEX && type.getComplexTypeName() != null) {
reader = ComplexFieldReader.createFromType(type);
} else {
reader = FieldReaders.create(columnName, type);
} Defensive patterns
Strategy: type-guard
Validate before calling
boolean usable = columnType != null && columnType.getType() == ValueType.COMPLEX && columnType.getComplexTypeName() != null;
Type guard
boolean isNamedComplex(ColumnType t) { return t != null && t.getType() == ValueType.COMPLEX && t.getComplexTypeName() != null; } Try / catch
try { reader = ComplexFieldReader.createFromType(t); } catch (IllegalStateException e) { reader = FieldReaders.create(name, t); } Prevention
- Verify complexTypeName is present in serialized column descriptors
- Route generic columns through FieldReaders.create, not createFromType
- Check ComplexMetrics registrations when reading data written elsewhere
When it happens
Trigger: Calling ComplexFieldReader.createFromType(columnType) with a null ColumnType; with a non-complex type (LONG, DOUBLE, STRING, ARRAY); or with a COMPLEX type whose complexTypeName is null, as happens when a complex column is deserialized from a descriptor missing the type name.
Common situations: Segment/column schema serialized by a version that did not persist complexTypeName; manually constructed ColumnType instances passed instead of ones parsed from the segment metadata; wiring a complex column through generic field-reader code paths that assume all types.
Related errors
- Aggregation [%s] does not support column [%s] of type [%s].
- Unknown schema %s
- Invalid Struct type.
- Missing type for column [%s]
- No serde for complexTypeName[%s]
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/c4c8faca2797e877.
Report an issue: GitHub.