apache/druid · error · IllegalStateException
Cannot handle inputSpec of class [%s]
Error message
Cannot handle inputSpec of class [%s]
What it means
MSQ's input-slicing framework dispatches each InputSpec type to a registered InputSpecSlicer via getSlicer. This ISE is thrown when an InputSpec class has no slicer registered in splitterMap, meaning the query contains an input spec type the current slicer does not know how to split across workers.
Source
Thrown at multi-stage-query/src/main/java/org/apache/druid/msq/input/MapInputSpecSlicer.java:71
@Override
public List<InputSlice> sliceDynamic(
InputSpec inputSpec,
@Nullable SegmentPruner segmentPruner,
int maxNumSlices,
int maxFilesPerSlice,
long maxBytesPerSlice
)
{
return getSlicer(inputSpec.getClass()).sliceDynamic(inputSpec, segmentPruner, maxNumSlices, maxFilesPerSlice, maxBytesPerSlice);
}
private InputSpecSlicer getSlicer(final Class<? extends InputSpec> clazz)
{
final InputSpecSlicer slicer = splitterMap.get(clazz);
if (slicer == null) {
throw new ISE("Cannot handle inputSpec of class [%s]", clazz.getName());
}
return slicer;
}
}
View on GitHub (pinned to 9b90983fd2)
Solutions
- Check the InputSpec class named in the message and confirm the Druid MSQ code path that produced it is supported for this query type.
- If you added a custom InputSpec, register a corresponding InputSpecSlicer in the MapInputSpecSlicer's splitterMap.
- Verify all Druid nodes (overlord, controller, worker) run the same version so InputSpec classes match.
- If triggered by an unsupported datasource (e.g. lookup or inline passed where only table/stage are supported), rewrite the query to use a supported input source.
Example fix
// before
final MapInputSpecSlicer slicer = new MapInputSpecSlicer(
ImmutableMap.of(TableInputSpec.class, tableSlicer));
slicer.sliceStatic(inputSpec, ...); // ISE for StageInputSpec
// after
final MapInputSpecSlicer slicer = new MapInputSpecSlicer(
ImmutableMap.of(
TableInputSpec.class, tableSlicer,
StageInputSpec.class, stageSlicer)); Defensive patterns
Strategy: try-catch
Validate before calling
if (!ImmutableSet.of(TableInputSpec.class, StageInputSpec.class).contains(inputSpec.getClass())) {
throw new UnsupportedOperationException("No slicer for " + inputSpec.getClass());
} Try / catch
try {
slicer.sliceStatic(inputSpec, maxSlices);
} catch (IllegalStateException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Cannot handle inputSpec of class")) {
log.error(e, "Unsupported input spec %s", inputSpec.getClass().getName());
} else {
throw e;
}
} Prevention
- Keep the splitterMap aligned with every InputSpec subclass in use.
- Run MSQ integration tests when adding new input spec types.
- Pin all Druid nodes to the same version.
When it happens
Trigger: Calling canSliceDynamic, sliceStatic, or sliceDynamic on a MapInputSpecSlicer whose splitterMap lacks an entry for the InputSpec subclass being sliced (e.g. a new InputSpec type added without updating the map, or an exotic data source deserialized from JSON).
Common situations: A custom extension registers a new InputSpec; a Druid version mismatch where one broker/overlord serializes a newer InputSpec that an older controller's MapInputSpecSlicer doesn't handle; wiring bugs where a slicer is constructed with a partial map of splitters.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Lookup[%s] has multiple segments; cannot read
- Stage[%d] output partitions not available
- FrameTooLarge
- Row [%d] out of bounds
- Table %s: not found
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/b083f27c81e2654d.
Report an issue: GitHub.