apache/druid · error · org.apache.druid.java.util.common.IAE
Unknown object type [ ]
Error message
Unknown object type [%s]
What it means
DoubleMeanAggregatorFactory.deserialize() reconstructs a DoubleMeanHolder from ByteBuffer, byte[], or base64 String (also passing through existing holders). Any other runtime type cannot originate from this aggregator's serialize() and signals a broken intermediate value, so it throws IAE with the value's class name.
Solutions
- Clear the segment result caches (or bump cache identifier/version) after changing aggregator types, then let values be re-populated.
- Run the value through finalizeComputation()/deserialize() consistently — only deserialize values produced by DoubleMeanAggregatorFactory.serialize().
- Re-ingest or rewrite affected segments so intermediate values are serialized holders.
- Wrap raw doubles into a DoubleMeanHolder (or its byte form) before calling deserialize-equivalent paths.
Example fix
// before
Object holder = factory.deserialize(someDouble);
// after
Object holder = (someDouble instanceof Double)
? new DoubleMeanHolder((Double) someDouble, 1L)
: factory.deserialize(someDouble); Defensive patterns
Strategy: type-guard
Validate before calling
if (object != null && !(object instanceof ByteBuffer) && !(object instanceof byte[]) && !(object instanceof String) && !(object instanceof DoubleMeanHolder)) { throw new IllegalArgumentException("Not a serialized DoubleMeanHolder: " + object.getClass()); } Type guard
boolean isDeserializable(Object o) { return o == null || o instanceof ByteBuffer || o instanceof byte[] || o instanceof String || o instanceof DoubleMeanHolder; } Try / catch
try { return factory.deserialize(object); } catch (IllegalArgumentException e) { /* value from wrong aggregator type: re-fetch or re-ingest */ } Prevention
- Only deserialize values produced by DoubleMeanAggregatorFactory.serialize().
- Invalidate caches when the metric's aggregator type changes.
- Verify segment intermediate formats after Druid upgrades.
- Guard generic pipelines: confirm factory type before deserialize.
When it happens
Trigger: Calling deserialize() with a raw Double, Long, Map, or null from segment/cache data not produced by doubleMean serialization — e.g. cache entries from a different aggregator type or hand-built results.
Common situations: Druid cache poisoning after changing the metric's aggregator type without clearing caches; cross-version storage format drift; custom code storing the raw finalized double and later trying to deserialize it.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- lhs[ ] or rhs[ ] not of type [ ]
- Cannot deserialize type
- Incompatible type for metric
- not supported
- not supported
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/94479aa7c11854c0.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/query/aggregation/mean/DoubleMeanAggregatorFactory.java:180
}
@Override
public AggregatorFactory getCombiningFactory()
{
return new DoubleMeanAggregatorFactory(name, name);
}
@Override
public Object deserialize(Object object)
{
if (object instanceof byte[]) {
return DoubleMeanHolder.fromBytes((byte[]) object);
} else if (object instanceof String) {
return DoubleMeanHolder.fromBytes(StringUtils.decodeBase64(StringUtils.toUtf8((String) object)));
} else if (object instanceof DoubleMeanHolder) {
return object;
} else {
throw new IAE("Unknown object type [%s]", Utils.safeObjectClassGetName(object));
}
}
@Nullable
@Override
public Object finalizeComputation(@Nullable Object object)
{
if (object instanceof byte[]) {
return DoubleMeanHolder.fromBytes((byte[]) object).mean();
} else if (object instanceof DoubleMeanHolder) {
return ((DoubleMeanHolder) object).mean();
} else if (object == null) {
return null;
} else {
throw new IAE("Unknown object type [%s]", object.getClass().getName());
}
}
View on GitHub (pinned to 9b90983fd2)