apache/rocketmq · error · IllegalArgumentException

illegal virtualNodeCnt :%d

Error message

illegal virtualNodeCnt :%d

What it means

AllocateMessageQueueConsistentHash's constructor rejects a negative virtualNodeCnt with IllegalArgumentException. Virtual node count multiplies each consumer's presence on the consistent-hash ring; a negative count is meaningless (zero is tolerated but degenerate). Typical healthy values are 10 (the default) and up.

Source

Thrown at client/src/main/java/org/apache/rocketmq/client/consumer/rebalance/AllocateMessageQueueConsistentHash.java:45

/**
 * Consistent Hashing queue algorithm
 */
public class AllocateMessageQueueConsistentHash extends AbstractAllocateMessageQueueStrategy {

    private final int virtualNodeCnt;
    private final HashFunction customHashFunction;

    public AllocateMessageQueueConsistentHash() {
        this(10);
    }

    public AllocateMessageQueueConsistentHash(int virtualNodeCnt) {
        this(virtualNodeCnt, null);
    }

    public AllocateMessageQueueConsistentHash(int virtualNodeCnt, HashFunction customHashFunction) {
        if (virtualNodeCnt < 0) {
            throw new IllegalArgumentException("illegal virtualNodeCnt :" + virtualNodeCnt);
        }
        this.virtualNodeCnt = virtualNodeCnt;
        this.customHashFunction = customHashFunction;
    }

    @Override
    public List<MessageQueue> allocate(String consumerGroup, String currentCID, List<MessageQueue> mqAll,
        List<String> cidAll) {

        List<MessageQueue> result = new ArrayList<>();
        if (!check(consumerGroup, currentCID, mqAll, cidAll)) {
            return result;
        }

        Collection<ClientNode> cidNodes = new ArrayList<>();
        for (String cid : cidAll) {
            cidNodes.add(new ClientNode(cid));
        }

View on GitHub (pinned to 293f588571)

Solutions

  1. Pass a positive count, e.g. new AllocateMessageQueueConsistentHash(10)
  2. Sanitize config values: Math.max(1, parsedValue)
  3. Treat -1 sentinel from config as 'use default' and substitute 10

Example fix

// before
new AllocateMessageQueueConsistentHash(cfg.getInt("vnode", -1));

// after
int vnode = cfg.getInt("vnode", 10);
new AllocateMessageQueueConsistentHash(Math.max(1, vnode));
Defensive patterns

Strategy: validation

Validate before calling

int vnode = Math.max(1, configuredVirtualNodeCnt);
new AllocateMessageQueueConsistentHash(vnode);

Prevention

When it happens

Trigger: new AllocateMessageQueueConsistentHash(-1) or passing a config-parsed integer that defaulted to -1/'not set' sentinel.

Common situations: Reading virtualNodeCnt from a config system where a missing key parses as -1; arithmetic like (nodes - expected) that goes negative when data is wrong.

Related errors


AI-assisted analysis of apache/rocketmq@293f588571 (2026-08-14). Data as JSON: /api/errors/ac93b7f72f81ad7f. Report an issue: GitHub.