apache/incubator-seata · error · IllegalArgumentException

worker Id can't be greater than %d or less than 0

Error message

worker Id can't be greater than %d or less than 0

What it means

IdWorker is Seata's snowflake-based ID generator. Its workerId occupies 10 bits (maxWorkerId, typically 1023), and initWorkerId validates the configured/generated worker id against that range. This IllegalArgumentException fires when workerId is negative or exceeds maxWorkerId, because shifting an out-of-range id would corrupt the generated UUID layout.

Source

Thrown at common/src/main/java/org/apache/seata/common/util/IdWorker.java:101

     * init first timestamp and sequence immediately
     */
    private void initTimestampAndSequence() {
        long timestamp = getNewestTimestamp();
        long timestampWithSequence = timestamp << sequenceBits;
        this.timestampAndSequence = new AtomicLong(timestampWithSequence);
    }

    /**
     * init workerId
     * @param workerId if null, then auto generate one
     */
    private void initWorkerId(Long workerId) {
        if (workerId == null) {
            workerId = generateWorkerId();
        }
        if (workerId > maxWorkerId || workerId < 0) {
            String message = String.format("worker Id can't be greater than %d or less than 0", maxWorkerId);
            throw new IllegalArgumentException(message);
        }
        this.workerId = workerId << (timestampBits + sequenceBits);
    }

    /**
     * get next UUID(base on snowflake algorithm), which look like:
     * highest 1 bit: always 0
     * next   10 bit: workerId
     * next   41 bit: timestamp
     * lowest 12 bit: sequence
     * @return UUID
     */
    public long nextId() {
        waitIfNecessary();
        long next = timestampAndSequence.incrementAndGet();
        long timestampWithSequence = next & timestampAndSequenceMask;
        return workerId | timestampWithSequence;
    }

View on GitHub (pinned to e01f97c6db)

Solutions

  1. Set workerId to a value in [0, 1023]
  2. Derive workerId from a stable small identifier such as the low 10 bits of a MAC hash or pod ordinal modulo 1024
  3. Pass null to let IdWorker auto-generate a workerId (MAC-based, falling back to random)

Example fix

// before
IdWorker worker = new IdWorker(5000); // > 1023, throws

// after
IdWorker worker = new IdWorker(5000 % 1024); // or pass null for auto-generation
Defensive patterns

Strategy: validation

Validate before calling

long MAX = (1L << 10) - 1; // 1023, matches worker id bits
if (workerId == null || workerId < 0 || workerId > 1023) workerId = Math.floorMod(podOrdinal, 1024);
IdWorker w = new IdWorker(workerId);

Prevention

When it happens

Trigger: Constructing IdWorker with an explicit workerId (e.g. new IdWorker(1024) or new IdWorker(-1)), or setting idWorkerId via configuration to a value above 1023 (or negative). If workerId is null one is auto-generated from MAC or randomly, which stays in range.

Common situations: A node index / pod ordinal (e.g. Kubernetes StatefulSet ordinal up to thousands) is fed directly as workerId; or an operator sets a worker id in a distributed deployment where the value was chosen without accounting for the 10-bit limit.

Related errors


AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14). Data as JSON: /api/errors/38145255d8b24f4b. Report an issue: GitHub.