apache/druid · error · ISE

Got a null result! Segments are missing!

Error message

Got a null result! Segments are missing!

What it means

Thrown by ChainedExecutionQueryRunner's per-segment runnable when a query runner's run() method returns a null Sequence. In Druid, every executed query must produce a non-null result sequence; null indicates the segment backing the runner is gone or the runner is broken. The library throws ISE to fail fast rather than propagate a NullPointerException later.

Source

Thrown at processing/src/main/java/org/apache/druid/query/ChainedExecutionQueryRunner.java:115

                    Iterables.transform(
                        queryables,
                        input -> {
                          if (input == null) {
                            throw new ISE("Null queryRunner! Looks to be some segment unmapping action happening");
                          }

                          final AbstractPrioritizedQueryRunnerCallable<Iterable<T>, T> callable = new AbstractPrioritizedQueryRunnerCallable<>(
                              priority,
                              input
                          )
                          {
                            @Override
                            public Iterable<T> call()
                            {
                              try {
                                Sequence<T> result = input.run(threadSafeQueryPlus, responseContext);
                                if (result == null) {
                                  throw new ISE("Got a null result! Segments are missing!");
                                }

                                List<T> retVal = result.toList();
                                if (retVal == null) {
                                  throw new ISE("Got a null list of results");
                                }

                                return retVal;
                              }
                              catch (QueryInterruptedException e) {
                                throw new RuntimeException(e);
                              }
                              catch (QueryTimeoutException e) {
                                throw e;
                              }
                              catch (Exception e) {
                                if (query.context().isDebug()) {
                                  log.error(e, "Exception with one of the sequences!");

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Check the historical node logs for segment load/drop events around the query time; re-fetch segment metadata from the coordinator
  2. Verify the segment is present on the node serving the query (segment cache dir, druid.segment-cache settings) and force re-download if missing
  3. Retry the query; if transient (segment swap during query), ensure query retry is enabled on the broker
  4. If a custom QueryRunner is in the stack, fix it to return Sequences.empty() or a valid Sequence instead of null

Example fix

// before
public Sequence<T> run(QueryPlus<T> query, Map<String, Object> context) {
  if (segmentMissing) {
    return null;
  }
  ...
}
// after
public Sequence<T> run(QueryPlus<T> query, Map<String, Object> context) {
  if (segmentMissing) {
    return Sequences.empty();
  }
  ...
}
Defensive patterns

Strategy: try-catch

Validate before calling

// before issuing query, verify segments served for the datasource/interval
SegmentMetadataQuery meta = new SegmentMetadataQuery(
    new TableDataSource("myDs"), Granularities.ALL, null, null, null);
// empty/missing segment metadata signals the segment may be absent

Type guard

boolean hasValidResult(Sequence<?> seq) {
  return seq != null;
}

Try / catch

try {
  Sequence<T> seq = runner.run(queryPlus, context);
} catch (IllegalStateException e) {
  if (e.getMessage().contains("null result")) {
    // treat as segment-missing: refresh segments and retry
  }
}

Prevention

When it happens

Trigger: A QueryRunner returned by the segment/loading walker returns null from run(), typically because the segment referenced by the query is no longer loaded, the timeline returned no segment but a runner was still registered, or a custom/extension QueryRunner violates the contract of returning a Sequence.

Common situations: Segments dropped by a kill task or retention policy while a query is in flight; historical node serving a segment that was removed from its segment cache; custom QueryRunner implementations (extensions, test stubs) that return null instead of Sequences.empty(); mismatched segment load/serve configuration after restarts.

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/87d52ae062b541fb. Report an issue: GitHub.