LMAX-Exchange/disruptor · error · IllegalArgumentException
n must be > 0 and < bufferSize
Error message
n must be > 0 and < bufferSize
What it means
Thrown by SingleProducerSequencer.next(int n) when n < 1 or n > bufferSize. Identical contract to the multi-producer variant: next(n) claims n slots and blocks until they are free; zero/negative is meaningless and n greater than the ring capacity would self-deadlock. Note this sequencer also asserts single-thread access (an AssertionError 'Accessed by two threads' covers that separate misuse).
Source
Thrown at src/main/java/com/lmax/disruptor/SingleProducerSequencer.java:140
* @see Sequencer#next()
*/
@Override
public long next()
{
return next(1);
}
/**
* @see Sequencer#next(int)
*/
@Override
public long next(final int n)
{
assert sameThread() : "Accessed by two threads - use ProducerType.MULTI!";
if (n < 1 || n > bufferSize)
{
throw new IllegalArgumentException("n must be > 0 and < bufferSize");
}
long nextValue = this.nextValue;
long nextSequence = nextValue + n;
long wrapPoint = nextSequence - bufferSize;
long cachedGatingSequence = this.cachedValue;
if (wrapPoint > cachedGatingSequence || cachedGatingSequence > nextValue)
{
cursor.setVolatile(nextValue); // StoreLoad fence
long minSequence;
while (wrapPoint > (minSequence = Util.getMinimumSequence(gatingSequences, nextValue)))
{
LockSupport.parkNanos(1L); // TODO: Use waitStrategy to spin?
}
View on GitHub (pinned to c871ca4982)
Solutions
- Guard the caller: skip empty batches, clamp or chunk batches to <= bufferSize.
- Increase bufferSize to at least the maximum batch, or split the batch.
- Verify you are not accidentally on ProducerType.SINGLE with multiple producer threads (which trips the same-thread assert).
Example fix
// before long hi = ringBuffer.next(items.size()); // items.size() == 0 or > bufferSize // after if (items.isEmpty()) return; long hi = ringBuffer.next(Math.min(items.size(), ringBuffer.getBufferSize()));
Defensive patterns
Strategy: validation
Validate before calling
if (n < 1 || n > ringBuffer.getBufferSize()) {
throw new IllegalArgumentException("claim must be in [1, bufferSize]");
}
long hi = ringBuffer.next(n); Prevention
- Skip empty batches before calling next().
- With ProducerType.SINGLE, also ensure exactly one producer thread.
When it happens
Trigger: Calling next(0), next(-1), or next(bufferSize + 1) on a ring buffer created with ProducerType.SINGLE — commonly next(list.size()) with an empty list or a list bigger than the ring.
Common situations: Empty-batch publish path not guarded; batch size configured above ring capacity after a capacity reduction; code shared between single- and multi-producer topologies hitting the single-producer validation first.
Related errors
- n must be > 0 and < bufferSize
- n must be > 0
- n must be > 0
- maxBatchSize must be greater than 0
- Both batchStartsAt and batchSize must be positive but got: b
AI-assisted analysis of LMAX-Exchange/disruptor@c871ca4982 (2026-08-14).
Data as JSON: /api/errors/191f8b7b427c1b8a.
Report an issue: GitHub.