LMAX-Exchange/disruptor · error · IllegalArgumentException
A batchSize of: {} with batchStatsAt of: {} will overrun the
Error message
A batchSize of: {} with batchStatsAt of: {} will overrun the available number of arguments: {} What it means
Thrown by RingBuffer.batchOverRuns during batch publishing when batchStartsAt + batchSize walks past the end of the supplied argument array. The message reports how many arguments actually remain from batchStartsAt; publishing would otherwise read beyond the array and copy garbage (or throw ArrayIndexOutOfBoundsException deep inside the ring).
Source
Thrown at src/main/java/com/lmax/disruptor/RingBuffer.java:944
final A[] arg0, final B[] arg1, final C[] arg2, final int batchStartsAt, final int batchSize)
{
checkBatchSizing(batchStartsAt, batchSize);
batchOverRuns(arg0, batchStartsAt, batchSize);
batchOverRuns(arg1, batchStartsAt, batchSize);
batchOverRuns(arg2, batchStartsAt, batchSize);
}
private void checkBounds(final int batchStartsAt, final int batchSize, final Object[][] args)
{
checkBatchSizing(batchStartsAt, batchSize);
batchOverRuns(args, batchStartsAt, batchSize);
}
private <A> void batchOverRuns(final A[] arg0, final int batchStartsAt, final int batchSize)
{
if (batchStartsAt + batchSize > arg0.length)
{
throw new IllegalArgumentException(
"A batchSize of: " + batchSize +
" with batchStatsAt of: " + batchStartsAt +
" will overrun the available number of arguments: " + (arg0.length - batchStartsAt));
}
}
private void translateAndPublish(final EventTranslator<E> translator, final long sequence)
{
try
{
translator.translateTo(get(sequence), sequence);
}
finally
{
sequencer.publish(sequence);
}
}
View on GitHub (pinned to c871ca4982)
Solutions
- Clamp the count to the remaining elements: n = Math.min(chunk, args.length - start).
- Double-check that batchStartsAt is an index into the SAME array being published.
- Write a boundary unit test for the final partial chunk.
Example fix
// before int count = batchSize; // last chunk overruns the array ringBuffer.publishEvents(translators, start, count); // after int count = Math.min(batchSize, translators.length - start); ringBuffer.publishEvents(translators, start, count);
Defensive patterns
Strategy: validation
Validate before calling
int count = Math.min(batchSize, args.length - batchStartsAt);
if (batchStartsAt + count > args.length) throw new IllegalArgumentException("batch overruns args"); Prevention
- Always clamp the last chunk with Math.min(chunk, remaining).
- Add a boundary unit test for the final partial chunk of every batch loop.
When it happens
Trigger: Calling publishEvents(translators, 8, 4) when translators.length == 10 (8 + 4 = 12 > 10); any variant (tryPublishEvents, publishEvents with arg arrays, varargs) where offset plus count exceeds the source array length.
Common situations: Chunking loop with an incorrect tail calculation (forgetting Math.min for the last chunk); reusing an offset from a previous larger batch; off-by-one where count includes an element outside the array.
Related errors
- Both batchStartsAt and batchSize must be positive but got: b
- The ring buffer cannot accommodate {} it only has space for
- n must be > 0 and < bufferSize
- bufferSize must not be less than 1
- bufferSize must be a power of 2
AI-assisted analysis of LMAX-Exchange/disruptor@c871ca4982 (2026-08-14).
Data as JSON: /api/errors/dbaf6be3f7a2fdf4.
Report an issue: GitHub.