aeron-io/aeron · error · IllegalArgumentException
position out of range: -
Error message
position out of range: -
What it means
Image.validatePosition() throws this IllegalArgumentException when a caller-supplied position is below the subscriber's current position or beyond the limit of the current term (currentTermStartOffset + termLength). Positions passed to controlled/subscriber advance APIs must fall within the readable window.
Solutions
- Clamp the requested position to [image.position(), currentTermStartPosition + termLength] before setting.
- Align the position to a valid frame boundary and to the current term's range; recompute from image.position() when in doubt.
- Persist enough metadata (termId + position) so restored positions remain within the image's window.
Example fix
// before
image.position(savedPosition);
// after
long min = image.position();
long max = (min - (min & (termLength - 1))) + termLength;
if (savedPosition >= min && savedPosition <= max) {
image.position(savedPosition);
} Defensive patterns
Strategy: validation
Validate before calling
long current = image.position();
long limit = (current - (current & (image.termLength() - 1))) + image.termLength();
if (targetPosition < current || targetPosition > limit) {
throw new IllegalArgumentException("position out of range: " + current + "-" + limit);
} Try / catch
try {
image.position(savedPosition);
} catch (IllegalArgumentException e) {
// clamp to image.position() and log the stale position
} Prevention
- Persist termId together with position and validate it on restore.
- Only set positions previously obtained from image.position().
- Recompute limits at call time; never cache them across term boundaries.
When it happens
Trigger: Calling Image position-setting methods (e.g. position(long)) with a position < currentPosition or > term-window limit; saving/restoring positions computed against a different term; miscomputed offsets after term rollover.
Common situations: Subscribers persisting and restoring positions across restarts with stale term metadata; manually advancing a subscription position past the term boundary; clock/ordering bugs where an older recorded position is replayed.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- position not aligned to FRAME_ALIGNMENT
- failed to write reject image command
- EINVAL
- index out of range
- Aeron client instance must set…
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/990b1ae8fb94102d.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-client/src/main/java/io/aeron/Image.java:783
* @param reason a String indicating the reason why this image is being rejected.
*/
public void reject(final String reason)
{
subscription.rejectImage(correlationId, position(), reason);
}
private UnsafeBuffer activeTermBuffer(final long position)
{
return termBuffers[LogBufferDescriptor.indexByPosition(position, positionBitsToShift)];
}
private void validatePosition(final long position)
{
final long currentPosition = subscriberPosition.get();
final long limitPosition = (currentPosition - (currentPosition & termLengthMask)) + termLengthMask + 1;
if (position < currentPosition || position > limitPosition)
{
throw new IllegalArgumentException(
position + " position out of range: " + currentPosition + "-" + limitPosition);
}
if (0 != (position & (FRAME_ALIGNMENT - 1)))
{
throw new IllegalArgumentException(position + " position not aligned to FRAME_ALIGNMENT");
}
}
LogBuffers logBuffers()
{
return logBuffers;
}
void close()
{
finalPosition = subscriberPosition.getVolatile();
eosPosition = LogBufferDescriptor.endOfStreamPosition(logBuffers.metaDataBuffer());View on GitHub (pinned to 6d60124e15)