apache/druid · error · QueryTimeoutException
url[ ] timed out
Error message
url[%s] timed out
What it means
JsonParserIterator lazily opens the HTTP response for a broker-to-data-node query by calling future.get() with the remaining query timeout. If the deadline expires before the InputStream is available, init() throws this timeoutQuery() error naming the downstream URL. It signals that the data server did not start returning the query result within the allotted time.
Solutions
- Increase the query timeout (timeout SQL/HTTP query parameter or druid.query.default.timeout) and retry
- Check the target data server's load and logs; scale out or tune its query processing threads
- Reduce query cost (narrow intervals, add filters, limit granularity) so it completes within the timeout
- Verify network connectivity/latency between broker and data nodes
Example fix
// before
client.query("SELECT * FROM wikiticker"); // default timeout
// after
client.query("SELECT * FROM wikiticker").timeout("10m"); // or set druid.query.default.timeout Defensive patterns
Strategy: retry
Validate before calling
// before issuing the query
final long budgetMillis = 600_000;
if (budgetMillis <= 0) { throw new IllegalArgumentException("query timeout must be positive"); }
// pass budgetMillis as the timeout parameter to the query Try / catch
try {
rows = iterator stream collect;
} catch (QueryTimeoutException | TimeoutException e) {
log.warn("Query timed out; retrying with larger budget");
// retry with increased timeout or back off
} Prevention
- Set an explicit query timeout larger than expected worst-case runtime
- Monitor historical/realtime server load and queue times
- Keep broker and data node clocks synchronized so timeout budgets are computed correctly
- Narrow query intervals and add filters to reduce runtime
When it happens
Trigger: Calling hasNext() or next() on the iterator when future.get(timeLeftMillis) throws TimeoutException, i.e. the embedded HTTP future for url[%s] did not complete within the remaining query timeout budget.
Common situations: Slow or overloaded historical/realtime servers, large scan/groupBy queries exceeding druid.query.default.timeout or the per-query timeout, network latency between broker and data nodes, or a query with hasTimeout=true whose budget was mostly consumed before this segment's response was requested.
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 interrupted
- Action [ ] failed for worker [ ] with status ( )
- An external HTTP table with a URI must also provide the…
- An external HTTP table with a URI must also provide the…
- At most one of 'druid.broker.segment.watchedTiers' and…
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/d3bae7d2dd291a19.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/main/java/org/apache/druid/client/JsonParserIterator.java:171
long timeLeftMillis = timeoutAt - System.currentTimeMillis();
return checkTimeout(timeLeftMillis);
}
private boolean checkTimeout(long timeLeftMillis)
{
if (hasTimeout && timeLeftMillis < 1) {
return true;
}
return false;
}
private void init()
{
if (jp == null) {
try {
long timeLeftMillis = timeoutAt - System.currentTimeMillis();
if (checkTimeout(timeLeftMillis)) {
throw timeoutQuery();
}
InputStream is = hasTimeout ? future.get(timeLeftMillis, TimeUnit.MILLISECONDS) : future.get();
if (is != null) {
jp = objectMapper.getFactory().createParser(is);
} else if (checkTimeout()) {
throw timeoutQuery();
} else {
// The InputStream is null and we have not timed out, there might be multiple reasons why we could hit this
// condition, guess that we are hitting it because of scatter-gather bytes. It would be better to be more
// explicit about why errors are happening than guessing, but this comment is being rewritten from a T-O-D-O,
// so the intent is just to document this better rather than do all of the logic to fix it. If/when we get
// this exception thrown for other reasons, it would be great to document what other reasons this can happen.
throw ResourceLimitExceededException.withMessage(
"Possibly max scatter-gather bytes limit reached while reading from url[%s].",
url
);
}View on GitHub (pinned to 9b90983fd2)