elastic/elasticsearch · error · IllegalArgumentException

Invalid value: ${x}

Error message

Invalid value: ${x}

What it means

TDigest.checkValue rejects NaN and infinite doubles before adding them as samples. The t-digest algorithm cannot represent an unrepresentable numeric value as a centroid, so add()/add(x,1) calls checkValue and throws IllegalArgumentException for NaN, POSITIVE_INFINITY, or NEGATIVE_INFINITY.

Source

Thrown at libs/tdigest/src/main/java/org/elasticsearch/tdigest/TDigest.java:113

     * Adds a sample to a histogram.
     *
     * @param x The value to add.
     * @param w The weight of this point.
     */
    public abstract void add(double x, long w);

    /**
     * Add a single sample to this TDigest.
     *
     * @param x The data value to add
     */
    public final void add(double x) {
        add(x, 1);
    }

    static void checkValue(double x) {
        if (Double.isNaN(x) || Double.isInfinite(x)) {
            throw new IllegalArgumentException("Invalid value: " + x);
        }
    }

    /**
     * Re-examines a t-digest to determine whether some centroids are redundant.  If your data are
     * perversely ordered, this may be a good idea.  Even if not, this may save 20% or so in space.
     *
     * The cost is roughly the same as adding as many data points as there are centroids.  This
     * is typically < 10 * compression, but could be as high as 100 * compression.
     *
     * This is a destructive operation that is not thread-safe.
     */
    public abstract void compress();

    /**
     * Returns the fraction of all points added which are ≤ x. Points
     * that are exactly equal get half credit (i.e. we use the mid-point
     * rule)

View on GitHub (pinned to db6a809a66)

Solutions

  1. Filter out non-finite values before adding: if (Double.isFinite(x)) digest.add(x)
  2. Treat NaN/Infinity as missing data and skip the sample, or replace with a defined sentinel the algorithm tolerates
  3. Audit upstream calculations for division by zero and overflow

Example fix

// before
digest.add(value); // value may be NaN/Infinity
// after
if (Double.isFinite(value)) {
    digest.add(value);
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (!Double.isFinite(x)) {
    // skip or record as missing
    return;
}
digest.add(x);

Type guard

static boolean isAddable(double x) { return Double.isFinite(x); }

Try / catch

try { digest.add(x); }
catch (IllegalArgumentException e) { /* drop sample */ }

Prevention

When it happens

Trigger: Calling tdigest.add(x) or tdigest.add(x, w) where x is Double.NaN, Double.POSITIVE_INFINITY, or Double.NEGATIVE_INFINITY. Also reached via add(TDigestReadView) if the other digest contains a bad mean.

Common situations: Feeding metric values from a source that emits NaN for missing data (division by zero upstream); log-derived doubles that overflow to infinity; sensor readings with sentinel NaN values; aggregations that produce infinity from max/min of unbounded streams.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/33b0c5ab0ad557e9. Report an issue: GitHub.