aeron-io/aeron · error · IllegalArgumentException

invalid length: " + length

Error message

invalid length: " + length

What it means

RecordingReader also validates the requested replay length. A length below NULL_LENGTH (a negative value other than the null sentinel) is meaningless, so the constructor throws IllegalArgumentException.

Solutions

  1. Use Aeron.NULL_LENGTH (-1) to request replay to the end of the recording.
  2. Ensure length is either NULL_LENGTH or a positive byte count; clamp negatives in client code.
  3. Check stop/start subtraction order when computing explicit replay lengths.
  4. Validate the replay request fields before sending them to the archive.

Example fix

// before
long length = stopPos - startPos; // stopPos < startPos -> negative
// after
long length = stopPos >= startPos ? stopPos - startPos : Aeron.NULL_LENGTH;
Defensive patterns

Strategy: validation

Validate before calling

if (length != Aeron.NULL_LENGTH && length < 0) {
    throw new IllegalArgumentException("length must be Aeron.NULL_LENGTH or positive");
}

Try / catch

try { replay(recId, position, length); }
catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("invalid length")) { clampLengthAndRetry(); }
}

Prevention

When it happens

Trigger: Constructing RecordingReader with length < NULL_LENGTH — a negative length passed through a replay request instead of NULL_LENGTH (-1, meaning 'to the end of the recording') or a positive byte count.

Common situations: Client computes replay length as stopPosition - startPosition with a reversed order; sending a negative length in a replay request message; confusing NULL_LENGTH with other sentinel values.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12). Data as JSON: /api/errors/79315e4986ec024b. Report an issue: GitHub.

Appendix: source

Thrown at aeron-archive/src/main/java/io/aeron/archive/RecordingReader.java:70

    private final long replayLimit;
    private long replayPosition;
    private long segmentFilePosition;
    private int termOffset;
    private int termBaseSegmentOffset;
    private boolean isDone = false;

    RecordingReader(
        final RecordingSummary recordingSummary, final File archiveDir, final long position, final long length)
    {
        if (position < NULL_POSITION)
        {
            throw new IllegalArgumentException("invalid position: " + position);
        }

        if (length < NULL_LENGTH)
        {
            throw new IllegalArgumentException("invalid length: " + length);
        }

        this.archiveDir = archiveDir;
        this.termLength = recordingSummary.termBufferLength;
        this.segmentLength = recordingSummary.segmentFileLength;
        this.recordingId = recordingSummary.recordingId;

        final long startPosition = recordingSummary.startPosition;
        final long fromPosition = position == NULL_POSITION ? startPosition : position;
        final long maxLength = recordingSummary.stopPosition != NULL_POSITION ?
            recordingSummary.stopPosition - fromPosition : Long.MAX_VALUE - fromPosition;

        final long replayLength = length == NULL_LENGTH ? maxLength : Math.min(length, maxLength);
        if (replayLength < 0)
        {
            throw new IllegalArgumentException("length must be positive");
        }

View on GitHub (pinned to 6d60124e15)