apache/druid · warning

Query interrupted, cancelling pending results for query

Error message

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

What it means

GroupByMergingQueryRunner.waitForFutureCompletion blocks on per-segment group-by futures and, on InterruptedException or CancellationException, cancels all outstanding futures and throws QueryInterruptedException after logging the query id. Like the chained runner, this is the cancellation/interruption cleanup path for the group-by v2 merging stage.

Solutions

  1. If the query was cancelled intentionally, this log is expected — no action needed
  2. Trace the cancellation source in broker logs (client disconnect vs explicit DELETE on /druid/v2)
  3. Tune group-by performance (groupBy maxOnDiskStorage, buffer sizes, numThreads) so queries finish before client-side timeouts trigger cancellation
  4. Set client read timeouts larger than query context timeout so the server isn't interrupted mid-merge

Example fix

// before: client timeout shorter than query timeout
// curl --max-time 30 ... while context timeout is 300s
// after: align timeouts
// curl --max-time 300 ... and {"context":{"timeout":300000}}
Defensive patterns

Strategy: try-catch

Validate before calling

// Bound query cost before submitting: check the interval and granularity are narrow
if (interval.toDurationMillis() > maxAllowedScanMillis) {
  throw new IllegalArgumentException("Query interval too large for group-by");
}

Try / catch

try {
  result = runner.run(queryPlus, responseContext).toList();
} catch (QueryInterruptedException e) {
  if (e.getCause() instanceof CancellationException || e.getCause() instanceof InterruptedException) {
    // treat as cancellation, release partial results
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: While waitForFutureCompletion waits on futures: the query is cancelled (cancellation endpoint or client disconnect propagation), or the merging thread is interrupted (broker shutdown, interrupt-based timeout).

Common situations: User cancels a heavy group-by query; broker or historical shutdown during merge; client timeout closes the HTTP connection, propagating cancellation to the merge phase.

Related errors


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

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/query/groupby/epinephelinae/GroupByMergingQueryRunner.java:392

      if (queryWatcher != null) {
        queryWatcher.registerQueryFuture(query, future);
      }

      if (hasTimeout && timeout <= 0) {
        throw new QueryTimeoutException();
      }

      final List<AggregateResult> results = hasTimeout ? future.get(timeout, TimeUnit.MILLISECONDS) : future.get();

      for (AggregateResult result : results) {
        if (!result.isOk()) {
          GuavaUtils.cancelAll(true, future, futures);
          throw new ResourceLimitExceededException(result.getReason());
        }
      }
    }
    catch (InterruptedException | CancellationException 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 (QueryTimeoutException | TimeoutException 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()));
      }
      throw new RuntimeException(e);
    }

View on GitHub (pinned to 9b90983fd2)