apache/druid · warning

Query interrupted, cancelling pending results for query

Error message

Query interrupted, cancelling pending results for query [%s]

What it means

ChainedExecutionQueryRunner.make() waits on per-segment futures and merges their results. On CancellationException or InterruptedException it cancels all remaining futures (GuavaUtils.cancelAll(true, ...)) and throws QueryInterruptedException, logging which query was interrupted. This is the fan-out runner's cleanup path for query cancellation or thread interruption.

Solutions

  1. Confirm the query was intentionally cancelled; this log is normal in that case
  2. Check broker logs for the originating cancellation reason (client disconnect vs explicit cancel)
  3. Reduce per-segment latency (increase numThreads, tune query timeouts) if cancellations come from client timeouts
  4. Ensure clients close connections properly so cancellation propagates and resources are freed promptly

Example fix

// before: client aborts without cancelling server-side
curl ... > /dev/null &  # killed, server keeps running until disconnect detection
// after: cancel explicitly
// curl -X DELETE "http://broker:8082/druid/v2/<queryId>" or set client socket/read timeouts to match query.timeout
Defensive patterns

Strategy: try-catch

Validate before calling

// Skip issuing a query you already know is cancelled
if (cancelledQueryIds.contains(queryId)) {
  throw new QueryInterruptedException(new CancellationException());
}

Try / catch

try {
  result = queryRunner.run(queryPlus, responseContext).toList();
} catch (QueryInterruptedException e) {
  if (e.getCause() instanceof CancellationException || e.getCause() instanceof InterruptedException) {
    log.info("Query %s was cancelled", query.getId()); // expected path
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: While future.get() is blocked waiting for a segment result: the query is cancelled via the cancellation endpoint, the client disconnects causing cancellation propagation, or the executing thread is interrupted (shutdown/timeout management).

Common situations: User cancels a long-running query from the Druid console/CLI; broker drops the HTTP connection to the client and cancels downstream work; server shutdown or interrupt-driven timeout on the query thread.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


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

Appendix: source

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

                            return queryProcessingPool.submitRunnerTask(callable);
                          }
                        }
                    )
                );

            ListenableFuture<List<Iterable<T>>> future = Futures.allAsList(futures);
            queryWatcher.registerQueryFuture(query, future);

            try {
              return new MergeIterable<>(
                  context.hasTimeout() ?
                      future.get(context.getTimeout(), TimeUnit.MILLISECONDS) :
                      future.get(),
                  ordering.nullsFirst()
              ).iterator();
            }
            catch (CancellationException | InterruptedException e) {
              log.noStackTrace().warn(e, "Query interrupted, cancelling pending results for query [%s]", query.getId());
              GuavaUtils.cancelAll(true, future, futures);
              throw new QueryInterruptedException(e);
            }
            catch (TimeoutException | QueryTimeoutException e) {
              log.noStackTrace().warn(e, "Query timeout, cancelling pending results for query [%s]", query.getId());
              GuavaUtils.cancelAll(true, future, futures);
              throw new QueryTimeoutException(StringUtils.nonStrictFormat("Query [%s] timed out", query.getId()));
            }
            catch (ExecutionException e) {
              log.noStackTrace().warn(e, "Query error, cancelling pending results for query [%s]", query.getId());
              GuavaUtils.cancelAll(true, future, futures);
              Throwable cause = e.getCause();
              // Nested per-segment future timeout
              if (cause instanceof TimeoutException) {
                throw new QueryTimeoutException(StringUtils.nonStrictFormat("Query timeout, cancelling pending results for query [%s]. Per-segment timeout exceeded.", query.getId()));
              }
              Throwables.throwIfUnchecked(cause);
              throw new RuntimeException(cause);

View on GitHub (pinned to 9b90983fd2)