alibaba/nacos · critical · IllegalStateException

Cumulative Weight calculate wrong , the sum of probabilities

Error message

Cumulative Weight calculate wrong , the sum of probabilities does not equals 1.

What it means

Thrown by Chooser.Ref.refresh during cumulative-weight calculation when the final cumulative weight does not equal 1.0 within a 0.0001 tolerance (IllegalStateException). This is a floating-point consistency guard — the individual weights normalized by their sum should always produce a cumulative array ending at exactly 1.0. If it fires, the weight values contain extreme values (infinite, NaN) that the clamping logic did not fully stabilize.

Source

Thrown at client/src/main/java/com/alibaba/nacos/client/naming/utils/Chooser.java:160

            int index = 0;
            for (Pair<T> item : itemsWithWeight) {
                double singleWeight = item.weight();
                //ignore item which weight is zero.see test_randomWithWeight_weight0 in ChooserTest
                if (singleWeight <= 0) {
                    continue;
                }
                
                exactWeight = singleWeight / originWeightSum;
                weights[index] = randomRange + exactWeight;
                randomRange = weights[index++];
            }
            
            double doublePrecisionDelta = 0.0001;
            
            if (index == 0 || (Math.abs(weights[index - 1] - 1) < doublePrecisionDelta)) {
                return;
            }
            throw new IllegalStateException(
                "Cumulative Weight calculate wrong , the sum of probabilities does not equals 1.");
        }
        
        @Override
        public int hashCode() {
            return itemsWithWeight.hashCode();
        }
        
        @SuppressWarnings("unchecked")
        @Override
        public boolean equals(Object other) {
            if (this == other) {
                return true;
            }
            if (other == null) {
                return false;
            }
            if (getClass() != other.getClass()) {

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Review instance weight values for extremes (infinite, NaN, or extremely large magnitudes) and normalize them to reasonable positive values.
  2. Ensure weights are finite positive doubles — the Chooser clamps infinite to 10000.0 and NaN to 1.0, but combinations can still break normalization.
  3. Report as a bug if using only normal finite positive weights — the algorithm should handle those correctly.
Defensive patterns

Strategy: validation

Validate before calling

for (Instance inst : instances) {
    double w = inst.getWeight();
    if (w <= 0 || Double.isInfinite(w) || Double.isNaN(w) || w > 1e6) {
        throw new IllegalArgumentException("Invalid instance weight: " + w);
    }
}

Try / catch

try {
    chooser.refresh(weightedPairs);
} catch (IllegalStateException e) {
    if (e.getMessage().contains("sum of probabilities")) {
        // normalize weights manually and retry
        LOGGER.error("Weight normalization failed, using equal weights", e);
        List<Pair<T>> equalWeights = items.stream()
            .map(i -> new Pair<>(i, 1.0))
            .collect(Collectors.toList());
        chooser.refresh(equalWeights);
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: The weights array is non-empty (index > 0) but the last element differs from 1.0 by more than 0.0001. This can happen with pathological weight values such as Double.MAX_VALUE, very large numbers that become infinite, or combinations of infinite and finite weights that break the normalization.

Common situations: Instance metadata or config specifies extreme weight values (e.g., 1e308); a bug producing NaN weights that slip past the isFinite checks; edge cases with single very-large-weight instance alongside many tiny ones causing precision loss beyond delta.

Related errors


AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14). Data as JSON: /api/errors/67ce789ce9a1248e. Report an issue: GitHub.