elastic/elasticsearch · error · IllegalArgumentException
q should be in [0,1], got ${q}
Error message
q should be in [0,1], got ${q} What it means
AVLTreeDigest.quantile(q) computes the value at quantile q. The contract requires q in the closed interval [0,1]; anything below 0 or above 1 throws IllegalArgumentException immediately, before any centroid lookup. With empty data it returns NaN, with a single centroid it returns that mean.
Source
Thrown at libs/tdigest/src/main/java/org/elasticsearch/tdigest/AVLTreeDigest.java:302
}
r += a.count();
// for the last element, assume right width is same as left
if (x < b.mean() + right) {
return (r + b.count() * interpolate(x, b.mean() - right, b.mean() + right)) / count;
}
return 1;
}
}
/**
* @param q The quantile desired. Can be in the range [0,1].
* @return The minimum value x such that we think that the proportion of samples is ≤ x is q.
*/
@Override
public double quantile(double q) {
if (q < 0 || q > 1) {
throw new IllegalArgumentException("q should be in [0,1], got " + q);
}
AVLGroupTree values = summary;
if (values.isEmpty()) {
// no centroids means no data, no way to get a quantile
return Double.NaN;
} else if (values.size() == 1) {
// with one data point, all quantiles lead to Rome
return values.iterator().next().mean();
}
// if values were stored in a sorted array, index would be the offset we are interested in
final double index = q * count;
// deal with min and max as a special case singletons
if (index <= 0) {
return min;
}View on GitHub (pinned to db6a809a66)
Solutions
- Convert percent-in to fraction: divide by 100.0 before calling quantile
- Clamp q to [0,1]: Math.max(0.0, Math.min(1.0, q))
- Reject or skip when Double.isNaN(q)
- Audit the upstream arithmetic that produced q
Example fix
// before double q = percentile; // percentile = 99.0 double v = digest.quantile(q); // throws // after double q = Math.max(0.0, Math.min(1.0, percentile / 100.0)); double v = digest.quantile(q);
Defensive patterns
Strategy: validation
Validate before calling
double q = percentile / 100.0;
if (Double.isNaN(q) || q < 0.0 || q > 1.0) {
throw new IllegalArgumentException("quantile out of range: " + q);
}
double v = digest.quantile(q); Type guard
static boolean isValidQuantile(double q) {
return !Double.isNaN(q) && q >= 0.0 && q <= 1.0;
} Try / catch
try { digest.quantile(q); }
catch (IllegalArgumentException e) { /* clamp or skip */ } Prevention
- Always convert percent to fraction (/100)
- Clamp at the boundary instead of trusting callers
- Guard NaN explicitly
When it happens
Trigger: Calling tdigest.quantile(q) where q is negative, > 1, NaN, or otherwise outside [0,1]. Common when q is computed from a ratio that can exceed the unit interval or from user-supplied percentiles divided incorrectly.
Common situations: Passing a percentile like 99 meaning 99% instead of 0.99; dividing by zero or null; computing q from an unbounded aggregation; feeding NaN from an upstream computation.
Related errors
- q should be in [0,1], got ${q}
- Invalid value: ${x}
- Can't use ${scaleFunction} as scale with ${this}
- filters cannot be null or empty
- Can't write raw bytes whose xcontent-type can't be guessed
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/7de78696aff80e64.
Report an issue: GitHub.