apache/druid · error · org.apache.druid.java.util.common.ISE
Can't get sketch from object of type [%s]
Error message
Can't get sketch from object of type [%s]
What it means
SketchHolder.getSketch() converts the holder's underlying object into an Apache DataSketches Theta Sketch. It only knows how to handle Sketch, Union, and Memory instances; anything else reaches the final else branch and throws an ISE. This indicates the holder was constructed with (or a value deserialized into) an object of an unsupported type.
Source
Thrown at extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/theta/SketchHolder.java:155
} else {
union.union(getSketch());
}
}
public Sketch getSketch()
{
if (cachedSketch != null) {
return cachedSketch;
}
if (obj instanceof Sketch) {
cachedSketch = (Sketch) obj;
} else if (obj instanceof Union) {
cachedSketch = ((Union) obj).getResult();
} else if (obj instanceof Memory) {
cachedSketch = deserializeFromMemory((Memory) obj);
} else {
throw new ISE("Can't get sketch from object of type [%s]", obj.getClass().getName());
}
return cachedSketch;
}
public double getEstimate()
{
if (cachedEstimate == null) {
cachedEstimate = getSketch().getEstimate();
}
return cachedEstimate.doubleValue();
}
public SketchEstimateWithErrorBounds getEstimateWithErrorBounds(int errorBoundsStdDev)
{
Sketch sketch = getSketch();
SketchEstimateWithErrorBounds result = new SketchEstimateWithErrorBounds(
getEstimate(),
sketch.getUpperBound(errorBoundsStdDev),View on GitHub (pinned to 9b90983fd2)
Solutions
- Check what object was passed to SketchHolder.of() and ensure it is a Sketch, Union, or Memory
- Unwrap nested SketchHolder values with holder.getSketch() before passing them to of()
- Align the datasketches-java dependency version across all Druid nodes so serialization round-trips produce known types
- Log obj.getClass().getName() (it is already in the message) and add a type check before constructing the holder
Example fix
// before
SketchHolder holder = SketchHolder.of(obj); // obj may be anything
Sketch sketch = holder.getSketch(); // may throw ISE
// after
if (obj instanceof SketchHolder) {
obj = ((SketchHolder) obj).getSketch();
}
if (!(obj instanceof Sketch) && !(obj instanceof Union) && !(obj instanceof Memory)) {
throw new IllegalArgumentException("Unsupported sketch object: " + obj.getClass());
}
SketchHolder holder = SketchHolder.of(obj); Defensive patterns
Strategy: type-guard
Validate before calling
if (!(obj instanceof Sketch) && !(obj instanceof Union) && !(obj instanceof Memory)) {
throw new IllegalArgumentException("Unsupported sketch object: " + obj.getClass().getName());
} Type guard
boolean isSketchable(Object o) {
return o instanceof Sketch || o instanceof Union || o instanceof Memory;
} Try / catch
try {
Sketch s = holder.getSketch();
} catch (IllegalStateException e) {
// log obj class from message; fall back to re-wrapping via Memory.wrap(rawBytes)
} Prevention
- Only pass Sketch, Union, or Memory instances to SketchHolder.of()
- Unwrap nested SketchHolder values before wrapping
- Pin the same datasketches-java version on all Druid nodes
- Log obj.getClass().getName() near construction sites to catch bad types early
When it happens
Trigger: Calling getSketch() (directly or via getEstimate(), equals(), hashCode(), or set operations) on a SketchHolder whose wrapped object is not a Sketch, Union, or Memory — e.g. after SketchHolder.of(someArbitraryObject) or deserializing a payload produced by an incompatible sketch version.
Common situations: Mixing DataSketches versions where serialized bytes yield an unexpected class; passing a nested SketchHolder instead of the raw sketch object; custom aggregation code stuffing a non-sketch object into SketchHolder.of(); classloader differences in federated/cluster deployments returning an unrecognized implementation.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Illegal type received while theta sketch merging [%s]
- Unknwon types [%s] and [%s]
- Cannot deserialize type[%s] to an RoaringBitmap64Counter:
- Expected a number or an instance of MergingDigest, but recei
- Invalid input [%s] of type [%s] for [%s] aggregator [%s]
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/75af7c31d37a4851.
Report an issue: GitHub.