apache/druid · error · IllegalStateException
Got a [ ] which isn't a
Error message
Got a [%s] which isn't a %s
What it means
TimeseriesQueryRunnerFactory's runner only accepts TimeseriesQuery instances. run() type-checks the incoming QueryPlus payload and throws ISE if some other query class reaches the timeseries runner — an internal dispatch/wiring bug.
Solutions
- Verify the query's JSON "query" type is "timeseries" and not altered in transit
- Check extension versions: all Druid components must run the same version (no mixed classpath)
- Ensure QueryRunnerFactory registrations map the correct query class to TimeseriesQueryRunnerFactory
- Capture the full failing query JSON and validate it deserializes to TimeseriesQuery
Example fix
// before
QueryRunner<Row> r = factoryMap.get("topn").createRunner(segment); // wired wrong
// after
QueryRunner<Result<TimeseriesResultValue>> r = factoryMap.get("timeseries").createRunner(segment); Defensive patterns
Strategy: type-guard
Validate before calling
if (!(queryPlus.getQuery() instanceof TimeseriesQuery)) { throw new IllegalArgumentException("wrong runner for query type " + queryPlus.getQuery().getClass()); } Type guard
static boolean isTimeseries(Query<?> q) { return q instanceof TimeseriesQuery; } Try / catch
try { return runner.run(queryPlus, ctx); }
catch (IllegalStateException e) { if (e.getMessage().startsWith("Got a [")) { throw new QueryInterruptedException(e); } throw e; } Prevention
- Keep all Druid components on identical versions
- Register factories with correct query class mappings
- Never rewrite the 'type' field of query JSON in transit
When it happens
Trigger: A QueryPlus carrying a non-TimeseriesQuery (e.g. TopNQuery, GroupByQuery) is routed to the timeseries query runner factory, typically due to custom QueryToolChest/wiring, incorrect query type registration, or broken deserialization of query type fields.
Common situations: Custom extensions registering query runners with the wrong type mapping, forwarding queries between clusters with modified 'query/type' fields, classpath mixing Druid versions where query types changed package/name.
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
- attempt to get boolean[] null vector from string[] only…
- attempt to get double[] from string[] only scalar binding
- attempt to get long[] from string[] only scalar binding
- Cannot call makeDimensionSelector on field of type
- Cannot cast [ ] to [ ] (Types.InvalidCastException from…
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/d2f9bf1da5f4a13a.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/query/timeseries/TimeseriesQueryRunnerFactory.java:109
TimeseriesQueryEngine engine,
CursorFactory cursorFactory,
@Nullable TimeBoundaryInspector timeBoundaryInspector
)
{
this.engine = engine;
this.cursorFactory = cursorFactory;
this.timeBoundaryInspector = timeBoundaryInspector;
}
@Override
public Sequence<Result<TimeseriesResultValue>> run(
QueryPlus<Result<TimeseriesResultValue>> queryPlus,
ResponseContext responseContext
)
{
Query<Result<TimeseriesResultValue>> input = queryPlus.getQuery();
if (!(input instanceof TimeseriesQuery)) {
throw new ISE("Got a [%s] which isn't a %s", input.getClass(), TimeseriesQuery.class);
}
return engine.process(
(TimeseriesQuery) input,
cursorFactory,
timeBoundaryInspector,
(TimeseriesQueryMetrics) queryPlus.getQueryMetrics()
);
}
}
}
View on GitHub (pinned to 9b90983fd2)