apache/druid · warning · QueryTimeoutException
Query timeout, cancelling pending results for query
Error message
Query timeout, cancelling pending results for query [%s]. Per-segment timeout exceeded.
What it means
When an ExecutionException surfaces a TimeoutException as its cause while collecting segment futures, ChainedExecutionQueryRunner.make() reports specifically that a per-segment timeout was exceeded. The log message and thrown QueryTimeoutException tell the user the timeout originated at the individual segment execution level, not the overall query budget.
Solutions
- Increase the per-segment timeout context value on the query
- Investigate the specific slow segment: check historical logs, segment size, whether it required a deep-store fetch, and warm it up (segment warming/cache)
- Reduce per-segment work via query filters or repartitioning overly large segments
- Check historical load (concurrency, GC, disk I/O) — per-segment timeouts usually indicate resource contention
Example fix
// before
query.getContext().put("timeout", "10000"); // per-segment budget too tight
// after
query.getContext().put("timeout", "60000"); // allow cold segments to load Defensive patterns
Strategy: try-catch
Validate before calling
// check segment sizes/row counts to spot oversized segments // SELECT segment_id, num_rows FROM sys.segments WHERE datasource='myDs'
Try / catch
try {
results = client.query(queryJson);
} catch (QueryTimeoutException e) {
if (e.getMessage().contains("Per-segment timeout exceeded")) {
// raise per-segment timeout or investigate the slow segment
}
} Prevention
- Raise the per-segment timeout context value for cold/large segments
- Keep segment sizes in the recommended range to bound per-segment work
- Warm caches for hot segments to avoid deep-store fetch delays
- Watch historical GC/disk metrics; per-segment timeouts often flag contention
When it happens
Trigger: A per-segment future (with its own timeout, e.g. via per-segment timeout context or segment-scoped executors) times out; the segment runner's future completes exceptionally with TimeoutException, wrapped by the outer future's ExecutionException.
Common situations: A single cold/slow segment (deep storage fetch, disk contention) blowing the per-segment deadline while other segments finish; per-segment timeout set too low for wide rows; historical under load so an individual segment scan exceeds its slice of the budget.
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.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Query [ ] timed out
- Query[ ] url[ ] timed out.
- A-Not-B requires at least 1 sketch
- Access-Check-Result
- Action [ ] failed for worker [ ] with status ( )
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/f2236523f6e25d28.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/query/ChainedExecutionQueryRunner.java:183
).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)