apache/druid · error · BadQueryContextException
Timeout [maxDefaultTimeout] must be a non negative value, bu
Error message
Timeout [maxDefaultTimeout] must be a non negative value, but was %d
What it means
Druid validates the `defaultTimeout` query-context key, which supplies the fallback query timeout. QueryContext.getDefaultTimeout throws BadQueryContextException when the configured value is negative, because a negative default timeout would produce an invalid query deadline. The literal "maxDefaultTimeout" in the message template is just the message's fixed label; the offending value comes from the DEFAULT_TIMEOUT_KEY context entry.
Source
Thrown at processing/src/main/java/org/apache/druid/query/QueryContext.java:532
);
}
@Nullable
public Duration getTimeoutDuration()
{
if (hasTimeout()) {
return Duration.ofMillis(getTimeout());
}
return null;
}
public long getDefaultTimeout()
{
final long defaultTimeout = getLong(QueryContexts.DEFAULT_TIMEOUT_KEY, QueryContexts.DEFAULT_TIMEOUT_MILLIS);
if (defaultTimeout >= 0) {
return defaultTimeout;
}
throw new BadQueryContextException(
StringUtils.format(
"Timeout [%s] must be a non negative value, but was %d",
QueryContexts.DEFAULT_TIMEOUT_KEY,
defaultTimeout
)
);
}
public void verifyMaxQueryTimeout(long maxQueryTimeout)
{
long timeout = getTimeout();
if (timeout > maxQueryTimeout) {
throw new BadQueryContextException(
StringUtils.format(
"Configured %s = %d is more than enforced limit of %d.",
QueryContexts.TIMEOUT_KEY,
timeout,
maxQueryTimeoutView on GitHub (pinned to 9b90983fd2)
Solutions
- Set the `defaultTimeout` context value to a non-negative millisecond value or remove it so QueryContexts.DEFAULT_TIMEOUT_MILLIS applies.
- If you intend 'no timeout', omit the key rather than using -1.
- Audit config generation scripts/templates for negative sentinel values leaking into query context.
- Catch BadQueryContextException and re-raise with the offending context key so operators can fix config quickly.
Example fix
// before
context.put("defaultTimeout", -1); // 'unlimited' sentinel from another system
// after
// omit the key entirely, or use a valid positive value
context.put("defaultTimeout", 300_000L); Defensive patterns
Strategy: validation
Validate before calling
Object dt = query.getContext().get("defaultTimeout");
if (dt instanceof Number && ((Number) dt).longValue() < 0) {
throw new IllegalArgumentException("defaultTimeout must be non-negative, got " + dt);
} Type guard
boolean isValidDefaultTimeout(Object v) {
return !(v instanceof Number) || ((Number) v).longValue() >= 0;
} Try / catch
try {
client.query(query);
} catch (BadQueryContextException e) {
if (e.getMessage().contains("defaultTimeout")) {
query.getContext().remove("defaultTimeout");
client.query(query); // retry with engine default
} else {
throw e;
}
} Prevention
- Treat -1 as invalid in Druid context even if other systems use it as 'unlimited'.
- Centralize query-context construction so defaults are set in one validated place.
- Review config templates that feed defaultTimeout for sentinel leakage.
- Log the full query context on submission failures to speed diagnosis.
When it happens
Trigger: Calling QueryContext.getDefaultTimeout() (via getTimeout() when no explicit timeout is set) when the context contains DEFAULT_TIMEOUT_KEY ("defaultTimeout") with a value < 0, e.g. `{"defaultTimeout": -1}`.
Common situations: Operators wiring a cluster- or tier-wide default timeout from config where a sentinel value like -1 (meaning 'unlimited' in some other system) was copied over; property-file mistakes; version changes where -1 semantics were never supported by Druid.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Timeout [timeout] must be a non negative value, but was %d
- Per-segment timeout [timeoutPerSegmentQuery] must be a non n
- Cannot set kafka property [group.id]. Property is randomly g
- Cannot set kafka property [auto.offset.reset]. Property will
- Cannot set kafka property [enable.auto.commit]. Property wil
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/f4b35edd2edd0ec0.
Report an issue: GitHub.