apache/druid · error · org.apache.druid.java.util.common.ISE
Object is not of a type that can be deserialized to a quanti
Error message
Object is not of a type that can be deserialized to a quantiles DoublesSketch: %s
What it means
DoublesSketchOperations.deserialize coerces an Object (typically from a query result or serialized field) into a quantiles DoublesSketch. It supports String (base64), byte[], and DoublesSketch instances; anything else — including null — is rejected with an IllegalStateException. This guards against feeding non-sketch data into sketch post-aggregators.
Source
Thrown at extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/quantiles/DoublesSketchOperations.java:44
import org.apache.druid.segment.data.SafeWritableMemory;
import java.nio.charset.StandardCharsets;
public class DoublesSketchOperations
{
public static final DoublesSketch EMPTY_SKETCH = DoublesSketch.builder().build();
public static DoublesSketch deserialize(final Object serializedSketch)
{
if (serializedSketch instanceof String) {
return deserializeFromBase64EncodedString((String) serializedSketch);
} else if (serializedSketch instanceof byte[]) {
return deserializeFromByteArray((byte[]) serializedSketch);
} else if (serializedSketch instanceof DoublesSketch) {
return (DoublesSketch) serializedSketch;
}
throw new ISE(
"Object is not of a type that can be deserialized to a quantiles DoublesSketch: %s",
serializedSketch == null ? "null" : serializedSketch.getClass()
);
}
public static DoublesSketch deserializeSafe(final Object serializedSketch)
{
if (serializedSketch instanceof String) {
return deserializeFromBase64EncodedStringSafe((String) serializedSketch);
} else if (serializedSketch instanceof byte[]) {
return deserializeFromByteArraySafe((byte[]) serializedSketch);
}
return deserialize(serializedSketch);
}
public static DoublesSketch deserializeFromBase64EncodedString(final String str)
{
return deserializeFromByteArray(StringUtils.decodeBase64(str.getBytes(StandardCharsets.UTF_8)));View on GitHub (pinned to 9b90983fd2)
Solutions
- Inspect the actual value's class (the message prints it) and ensure the field being consumed is the raw sketch bytes/base64 string, not a decoded structure.
- Fix the upstream aggregation/post-aggregator chain so the field computes a DoublesSketch (e.g. use quantilesDoublesSketch aggregation directly).
- If the value is JSON-deserialized into a Map/List, re-serialize to base64 byte[] or store as raw bytes at ingestion time.
- Handle null explicitly: verify the column actually contains sketch data for every row instead of relying on deserialize to cope with null.
Example fix
// before
Object val = results.get("sketch"); // a List<Double> after JSON round-trip
DoublesSketch s = DoublesSketchOperations.deserialize(val); // ISE
// after
DoublesSketch s = DoublesSketchOperations.deserialize(
base64Encode(reSerializeAsSketchBytes(val))); // pass String or byte[] Defensive patterns
Strategy: type-guard
Validate before calling
if (val == null || !(val instanceof String || val instanceof byte[] || val instanceof DoublesSketch)) { throw new IllegalArgumentException("field must be base64 String, byte[], or DoublesSketch, got: " + (val == null ? "null" : val.getClass())); } Type guard
static boolean isSketchLike(Object o) { return o instanceof DoublesSketch || o instanceof byte[] || o instanceof String; } Try / catch
try { DoublesSketch s = DoublesSketchOperations.deserialize(val); } catch (IllegalStateException e) { log.error("Non-sketch value: {}", e.getMessage()); } Prevention
- Keep sketch fields as raw bytes through ingestion and query results (avoid JSON round-trips that decode them).
- Verify column metric type is the sketch aggregator, not a generic serializer.
- Log/inspect obj.getClass() before deserializing dynamically-typed results.
When it happens
Trigger: Calling deserialize() (directly or via callers like deserializeSafe consumers) with an Object whose runtime type is not String, byte[], or DoublesSketch — e.g. a Map, List, Number, or null returned from a previous stage or stored field.
Common situations: Group-by results where the sketch column was coerced to a JSON map/array, ingestion storing the wrong metric type in the column, passing the output of a different post-aggregator (e.g. a double[] histogram) into a sketch post-agg.
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
- 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
- Object is not of a type that can deserialize to sketch: %s
- Cannot deserialize type[%s] to an RoaringBitmap64Counter:
- Object is not of a type[%s] that can be deserialized to sket
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/4d9fa2e44007f15f.
Report an issue: GitHub.