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
- Set workerId to a value in [0, 1023]
- Derive workerId from a stable small identifier such as the low 10 bits of a MAC hash or pod ordinal modulo 1024
- 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
- Assign worker ids from a bounded pool [0,1023]
- Never feed raw pod ordinals or node indexes without modulo
- Record the chosen workerId in logs to detect collisions
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
- not found service provider for : {}
- Invalid port number in: {}
- Invalid format for endpoint: {}
- unknown lock mode:{}
- unknown session mode:{}
AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14).
Data as JSON: /api/errors/38145255d8b24f4b.
Report an issue: GitHub.