apache/druid · error

Query error, cancelling pending results for query

Error message

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

What it means

ChainedExecutionQueryRunner.make() catches ExecutionException when a per-segment future fails, cancels all sibling futures, and logs 'Query error, cancelling pending results'. The cause is then re-thrown as the appropriate QueryInterruptedException/QueryTimeoutException or propagated as a query failure. This is the aggregate error path for any segment-level query failure.

Solutions

  1. Inspect the nested cause in the log and downstream broker response for the true segment error
  2. If ResourceLimitExceededException, raise maxOnDiskStorage/maxMergingThreads or tune group-by buffers, or reduce query scope
  3. If per-segment TimeoutException, increase the query context timeoutMs or prioritize the segment loading
  4. Check historical node health/segment loading (coordinator logs, segment availability) if errors mention missing segments
  5. Retry the query if the failure was due to a transient node restart or network blip

Example fix

// before
{"queryType":"groupBy","...}
// after: raise limits and timeout in context
// {"queryType":"groupBy", ..., "context":{"timeout":300000,"maxOnDiskStorage":4000000000,"groupBy.maxOnDiskStorage":4000000000}}
Defensive patterns

Strategy: try-catch

Validate before calling

// Check segment availability before querying
// GET /druid/coordinator/v1/datasources/<ds>/segments is fully loaded
boolean allLoaded = coordinatorSegments.stream()
    .allMatch(s -> "loaded".equals(s.toLowerCase()));

Try / catch

try {
  result = queryClient.run(query);
} catch (DruidException e) {
  if (e.getErrorClass().contains("ResourceLimitExceeded")) {
    query = withRaisedLimits(query); // retry once with bigger buffers/timeout
    result = queryClient.run(query);
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Any per-segment computation future completes exceptionally: segment loading errors, resource limit exceptions, query timeouts inside a segment, timeouts nested as TimeoutException causes, or data/node failures during the query.

Common situations: Historical node dies or times out mid-query; a segment fails to load (bad segment, missing local cache files); ResourceLimitExceededException from too many group-by/agg results; per-segment timeout (timeoutMs in query context) exceeded.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


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

Appendix: source

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

              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);
            }
          }

          @Override
          public void cleanup(Iterator<T> tIterator)
          {

          }
        }
    );

View on GitHub (pinned to 9b90983fd2)