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

  1. Ensure the query routed to this runner is a TimeBoundaryQuery (queryType 'timeBoundary')
  2. Check the QueryRunnerFactoryConglomerate/SegmentWalker wiring so each query type maps to its own factory
  3. If using custom code, verify the query class before obtaining the runner from the conglomerate
  4. 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

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


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/5f98bb272d35c333. Report an issue: GitHub.