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
MergingDigest.quantile(q) is the MergingTDigest variant of the quantile lookup. It enforces the same [0,1] contract as AVLTreeDigest and throws IllegalArgumentException for any q outside it before merging new values and reading centroids. Behaviour for empty/single-centroid digests mirrors AVLTreeDigest.
Source
Thrown at libs/tdigest/src/main/java/org/elasticsearch/tdigest/MergingDigest.java:487
weightSoFar += weight.get(i);
left = right;
}
// for the last element, assume right width is same as left
int lastOffset = lastUsedCell - 1;
double right = (mean.get(lastOffset) - mean.get(lastOffset - 1)) / 2;
if (x < mean.get(lastOffset) + right) {
return (weightSoFar + weight.get(lastOffset) * interpolate(x, mean.get(lastOffset) - right, mean.get(lastOffset) + right))
/ size();
}
return 1;
}
}
@Override
public double quantile(double q) {
if (q < 0 || q > 1) {
throw new IllegalArgumentException("q should be in [0,1], got " + q);
}
mergeNewValues();
if (lastUsedCell == 0) {
// no centroids means no data, no way to get a quantile
return Double.NaN;
} else if (lastUsedCell == 1) {
// with one data point, all quantiles lead to Rome
return mean.get(0);
}
// we know that there are at least two centroids now
int n = lastUsedCell;
// if values were stored in a sorted array, index would be the offset we are interested in
final double index = q * totalWeight;
// beyond the boundaries, we return min or maxView on GitHub (pinned to db6a809a66)
Solutions
- Pass q in [0,1]; convert percentages by dividing by 100
- Clamp: Math.max(0.0, Math.min(1.0, q))
- Guard against NaN before calling
Example fix
// before double v = digest.quantile(p); // p = 1.5 // after double v = digest.quantile(Math.max(0.0, Math.min(1.0, p)));
Defensive patterns
Strategy: validation
Validate before calling
if (Double.isNaN(q) || q < 0.0 || q > 1.0) {
throw new IllegalArgumentException("quantile out of range: " + q);
}
return 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) { /* log and degrade */ } Prevention
- Share a single clamp helper across AVLTreeDigest and MergingDigest call sites
- Treat percentile inputs as untrusted
- Reject NaN upstream
When it happens
Trigger: Calling mergingDigest.quantile(q) with q < 0, q > 1, or q = NaN. This variant first validates then calls mergeNewValues(), so the throw happens before any merging work.
Common situations: Same family of bugs as AVLTreeDigest: percent-vs-fraction confusion, unbounded ratios, NaN propagation, off-by-one in array indexing that produces the quantile argument.
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/58cf3f7cba595a0e.
Report an issue: GitHub.