apache/druid · error · ParseException
Object cannot be deserialized to a Spectator Histogram
Error message
Object cannot be deserialized to a Spectator Histogram
What it means
SpectatorHistogram.deserialize expects the incoming object to be a HashMap whose keys are bucket indices and whose values are counts (Numbers). If the serialized object is any other type, the library cannot rebuild a histogram and throws this ParseException. It exists to fail fast on malformed or unexpected payloads rather than silently producing an empty histogram.
Source
Thrown at extensions-contrib/spectator-histogram/src/main/java/org/apache/druid/spectator/histogram/SpectatorHistogram.java:184
HashMap<String, Long> map = JSON_MAPPER.readerFor(HashMap.class).readValue((String) serializedHistogram);
SpectatorHistogram histogram = new SpectatorHistogram();
for (Map.Entry<String, Long> entry : map.entrySet()) {
histogram.add(entry.getKey(), entry.getValue());
}
return histogram;
}
catch (JsonProcessingException e) {
throw new ParseException((String) serializedHistogram, e, "String cannot be deserialized as JSON to a Spectator Histogram");
}
}
if (serializedHistogram instanceof HashMap) {
SpectatorHistogram histogram = new SpectatorHistogram();
for (Map.Entry<?, ?> entry : ((HashMap<?, ?>) serializedHistogram).entrySet()) {
histogram.add(entry.getKey(), (Number) entry.getValue());
}
return histogram;
}
throw new ParseException(
null,
"Object cannot be deserialized to a Spectator Histogram "
+ serializedHistogram.getClass()
);
}
@Nullable
static SpectatorHistogram fromByteBuffer(ByteBuffer buffer)
{
if (buffer == null || !buffer.hasRemaining()) {
return null;
}
SpectatorHistogram histogram = new SpectatorHistogram();
while (buffer.hasRemaining()) {
short key = buffer.getShort();
short idx = (short) (key & KEY_MASK);
long val;
if ((key & LOW_COUNT_FLAG) == LOW_COUNT_FLAG) {View on GitHub (pinned to 9b90983fd2)
Solutions
- Check that the value passed to deserialize is a HashMap of bucket-index -> count before calling it; reject or log other types upstream.
- Verify the serialization side uses SpectatorHistogram.serialize / the matching serde so the payload shape matches.
- If ingesting JSON, make sure the column is declared with the spectator histogram sketch type, not a plain numeric column.
Example fix
// before
Object obj = row.get("hist");
SpectatorHistogram h = SpectatorHistogram.deserialize(obj);
// after
if (!(obj instanceof HashMap)) {
throw new IAE("Expected serialized histogram map, got " + obj.getClass());
}
SpectatorHistogram h = SpectatorHistogram.deserialize(obj); Defensive patterns
Strategy: type-guard
Validate before calling
if (obj == null || !(obj instanceof HashMap)) {
throw new IAE("Cannot deserialize " + (obj == null ? "null" : obj.getClass()) + " as SpectatorHistogram");
} Type guard
boolean isSerializedHistogram(Object o) {
return o instanceof HashMap;
} Try / catch
try {
SpectatorHistogram h = SpectatorHistogram.deserialize(obj);
} catch (ParseException e) {
log.warn(e, "Bad histogram payload: %s", obj == null ? "null" : obj.getClass());
h = new SpectatorHistogram();
} Prevention
- Only deserialize payloads produced by SpectatorHistogram's own serde.
- Type-check with instanceof before calling deserialize.
- Pin matching versions of the extension on ingestion and query nodes.
When it happens
Trigger: Calling SpectatorHistogram.deserialize(Object) with a value that is not a HashMap — e.g. a plain Number, String, List, or a custom map type produced by a different serializer version.
Common situations: A Druid segment or query payload was serialized by an older/newer serializer that wraps histograms differently; a user hand-crafted JSON for a post-aggregator where the histogram is a scalar; deserializing a field that was never actually a SpectatorHistogram (column type confusion).
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- Cannot deserialize type[%s] to an RoaringBitmap64Counter:
- Cannot add / to a Spectator Histogram
- Object is not of a type[%s] that can be deserialized to sket
- Object is not of a type that can be deserialized to a quanti
- Object is not of a type that can be deserialized to a KllFlo
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/adc942e2c3b34644.
Report an issue: GitHub.