apache/dubbo · error · IllegalArgumentException

Illegal initial capacity: ${maxCapacity}

Error message

Illegal initial capacity: ${maxCapacity}

What it means

LFUCache constructor validates that maxCapacity is positive; a zero or negative capacity is rejected because the cache cannot operate with no slots (it also sizes the internal freqTable to capacity+1).

Source

Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/utils/LFUCache.java:52

    private static final float DEFAULT_EVICTION_FACTOR = 0.75f;

    public LFUCache() {
        this(DEFAULT_INITIAL_CAPACITY, DEFAULT_EVICTION_FACTOR);
    }

    /**
     * Constructs and initializes cache with specified capacity and eviction
     * factor. Unacceptable parameter values followed with
     * {@link IllegalArgumentException}.
     *
     * @param maxCapacity    cache max capacity
     * @param evictionFactor cache proceedEviction factor
     */
    @SuppressWarnings("unchecked")
    public LFUCache(final int maxCapacity, final float evictionFactor) {
        if (maxCapacity <= 0) {
            throw new IllegalArgumentException("Illegal initial capacity: " + maxCapacity);
        }
        boolean factorInRange = evictionFactor <= 1 && evictionFactor > 0;
        if (!factorInRange || Float.isNaN(evictionFactor)) {
            throw new IllegalArgumentException("Illegal eviction factor value:" + evictionFactor);
        }
        this.capacity = maxCapacity;
        this.evictionCount = (int) (capacity * evictionFactor);
        this.map = new HashMap<>();
        this.freqTable = new CacheDeque[capacity + 1];
        for (int i = 0; i <= capacity; i++) {
            freqTable[i] = new CacheDeque<>();
        }
        for (int i = 0; i < capacity; i++) {
            freqTable[i].nextDeque = freqTable[i + 1];
        }
        freqTable[capacity].nextDeque = freqTable[capacity];
    }

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Ensure the configured cache capacity is at least 1
  2. Compute capacity defensively and clamp to a minimum, or skip cache creation when the intended size is 0
  3. Validate the config property at load time rather than at cache construction

Example fix

// before
LFUCache<String,String> c = new LFUCache<>(0, 0.8f);
// after
int cap = Math.max(1, configuredCap);
LFUCache<String,String> c = new LFUCache<>(cap, 0.8f);
Defensive patterns

Strategy: validation

Validate before calling

int cap = configuredCapacity;
if (cap <= 0) throw new IllegalArgumentException("cache capacity must be > 0: " + cap);
new LFUCache<>(cap, 0.8f);

Type guard

static boolean validCapacity(int c) { return c > 0; }

Try / catch

try { new LFUCache<>(cap, factor); }
catch (IllegalArgumentException e) { /* cap <= 0; supply default */ }

Prevention

When it happens

Trigger: Instantiating new LFUCache(capacity, factor) with capacity <= 0, e.g. from a config value that defaulted to 0 or an arithmetic underflow computing the size.

Common situations: Cache-size properties that were never set and default to 0; size calculations like (total / divisor) yielding 0 for small inputs; tests that construct with literal 0.

Related errors


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