apache/dubbo · error · IllegalArgumentException

expectedSize cannot be negative but was: {expectedSize}

Error message

expectedSize cannot be negative but was: {expectedSize}

What it means

Thrown by CollectionUtils.capacity when expectedSize is negative. capacity() computes an optimal HashMap/HashSet initial capacity for a given element count (mirroring Guava's Maps.newHashMapWithExpectedSize sizing). A negative count is meaningless for sizing and is rejected; counts 0..2 return count+1, larger counts apply the 0.75 load-factor formula.

Source

Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/utils/CollectionUtils.java:474

    public static <K, T> Map<K, T> newConcurrentHashMap(int expectedSize) {
        if (JRE.JAVA_8.isCurrentVersion()) {
            return new SafeConcurrentHashMap<>(capacity(expectedSize));
        }
        return new ConcurrentHashMap<>(capacity(expectedSize));
    }

    public static <K, T> Map<K, T> newConcurrentHashMap() {
        if (JRE.JAVA_8.isCurrentVersion()) {
            return new SafeConcurrentHashMap<>();
        }
        return new ConcurrentHashMap<>();
    }

    public static int capacity(int expectedSize) {
        if (expectedSize < 3) {
            if (expectedSize < 0) {
                throw new IllegalArgumentException("expectedSize cannot be negative but was: " + expectedSize);
            }
            return expectedSize + 1;
        }
        if (expectedSize < 1 << (Integer.SIZE - 2)) {
            return (int) (expectedSize / 0.75F + 1.0F);
        }
        return Integer.MAX_VALUE;
    }

    public static class SafeConcurrentHashMap<K, V> extends ConcurrentHashMap<K, V> {
        private static final long serialVersionUID = 1L;

        public SafeConcurrentHashMap() {}

        public SafeConcurrentHashMap(int initialCapacity) {
            super(initialCapacity);
        }

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Clamp expectedSize to 0 before calling: capacity(Math.max(0, expectedSize)).
  2. Fix the upstream calculation that produced a negative size.
  3. Validate input at the boundary if expectedSize comes from external/config data.

Example fix

// before
int cap = CollectionUtils.capacity(computedSize); // computedSize may be -1

// after
int cap = CollectionUtils.capacity(Math.max(0, computedSize));
Defensive patterns

Strategy: validation

Validate before calling

int expectedSize = /* ... */;
if (expectedSize < 0) expectedSize = 0;
int cap = CollectionUtils.capacity(expectedSize);

Type guard

static boolean isNonNegative(int v) { return v >= 0; }

Prevention

When it happens

Trigger: CollectionUtils.capacity(expectedSize) where expectedSize < 0. Typically called internally by newHashMapWithExpectedSize / newConcurrentHashMap helpers, but exposed publicly. A negative input reaches it through a computed size (e.g. a list.size() result miscalculated, or a subtraction underflow).

Common situations: Passing a size derived from arithmetic that went negative (overflow, subtraction underflow); feeding an unchecked external value into capacity. Rare in correct code; indicates an upstream size-calculation bug.

Related errors


AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14). Data as JSON: /api/errors/badb8adae47fe28a. Report an issue: GitHub.