apache/druid · error · IllegalStateException
Got a [%s] which isn't a %s
Error message
Got a [%s] which isn't a %s
What it means
TimeBoundaryQueryRunnerFactory's QueryRunner.run() checks that the incoming QueryPlus actually wraps a TimeBoundaryQuery before executing it against the segment, throwing an IllegalStateException (ISE) if not. This is an internal contract check: timeboundary runners are registered only for TimeBoundaryQuery, so receiving any other query type means a dispatcher/registry bug or a misconstructed runner chain. The message includes the offending query class and the expected class.
Source
Thrown at processing/src/main/java/org/apache/druid/query/timeboundary/TimeBoundaryQueryRunnerFactory.java:117
@Nullable
private final TimeBoundaryInspector timeBoundaryInspector;
public TimeBoundaryQueryRunner(Segment segment)
{
this.cursorFactory = segment.as(CursorFactory.class);
this.dataInterval = segment.getDataInterval();
this.timeBoundaryInspector = segment.as(TimeBoundaryInspector.class);
}
@Override
public Sequence<Result<TimeBoundaryResultValue>> run(
final QueryPlus<Result<TimeBoundaryResultValue>> queryPlus,
final ResponseContext responseContext
)
{
Query<Result<TimeBoundaryResultValue>> input = queryPlus.getQuery();
if (!(input instanceof TimeBoundaryQuery)) {
throw new ISE("Got a [%s] which isn't a %s", input.getClass(), TimeBoundaryQuery.class);
}
final TimeBoundaryQuery query = (TimeBoundaryQuery) input;
return new BaseSequence<>(
new BaseSequence.IteratorMaker<>()
{
@Override
public Iterator<Result<TimeBoundaryResultValue>> make()
{
if (cursorFactory == null) {
throw new ISE(
"Null cursor factory found. Probably trying to issue a query against a segment being memory unmapped."
);
}
DateTime minTime = null;
DateTime maxTime = null;View on GitHub (pinned to 9b90983fd2)
Solutions
- Ensure the query routed to this runner is a TimeBoundaryQuery (queryType 'timeBoundary')
- Check the QueryRunnerFactoryConglomerate/SegmentWalker wiring so each query type maps to its own factory
- If using custom code, verify the query class before obtaining the runner from the conglomerate
- Update or remove any custom QueryRunnerFactory registrations that handle foreign query types
Example fix
// before
QueryRunner<Result<TimeBoundaryResultValue>> runner = factory.createRunner(segment);
runner.run(QueryPlus.wrap(scanQuery), responseContext); // ISE
// after
if (query instanceof TimeBoundaryQuery) {
runner.run(QueryPlus.wrap(query), responseContext);
} else {
runner = conglomerate.getRunner(query, segment);
} Defensive patterns
Strategy: type-guard
Validate before calling
if (!(query instanceof TimeBoundaryQuery)) {
throw new IllegalArgumentException("timeboundary runner requires a TimeBoundaryQuery, got " + query.getClass());
} Type guard
boolean isTimeBoundaryQuery(Query<?> q) {
return q instanceof org.apache.druid.query.timeboundary.TimeBoundaryQuery;
} Try / catch
try {
return runner.run(QueryPlus.wrap(query), responseContext);
} catch (IllegalStateException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Got a [")) {
// wrong runner for this query type: re-route via conglomerate
return conglomerate.getRunner(query, segment).run(QueryPlus.wrap(query), responseContext);
}
throw e;
} Prevention
- Obtain runners from QueryRunnerFactoryConglomerate instead of hand-wiring factories
- Keep custom SegmentWalker code type-dispatched per query class
- Verify factory registrations when writing Druid extensions
- Assert query types in tests that exercise custom runner chains
When it happens
Trigger: Calling run() on a TimeBoundaryQueryRunnerFactory-created runner with a QueryPlus whose query is not a TimeBoundaryQuery, e.g. a query of another type being routed to the timeboundary runner via a misconfigured QueryRunnerFactoryConglomerate or custom segment walker.
Common situations: Custom query tooling building runner chains manually and pairing the wrong factory with a query; plugins or tests registering the timeboundary factory for other query types; segment walkers returning runners in the wrong order so a foreign query hits the wrong runner.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Cannot deserialize type[%s] to an RoaringBitmap64Counter:
- Expected a number or an instance of MergingDigest, but recei
- 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 be deserialized to a quanti
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/5f98bb272d35c333.
Report an issue: GitHub.