{"record":{"id":"492463600548c4d6","repo":"aeron-io/aeron","slug":"invalid-position-position","errorCode":null,"errorMessage":"invalid position: \" + position","messagePattern":"invalid position: \" \\+ position","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"aeron-archive/src/main/java/io/aeron/archive/RecordingReader.java","lineNumber":65,"sourceCode":"    private final int segmentLength;\n    private final int termLength;\n\n    private final UnsafeBuffer termBuffer;\n    private MappedByteBuffer mappedSegmentBuffer;\n\n    private final long replayLimit;\n    private long replayPosition;\n    private long segmentFilePosition;\n    private int termOffset;\n    private int termBaseSegmentOffset;\n    private boolean isDone = false;\n\n    RecordingReader(\n        final RecordingSummary recordingSummary, final File archiveDir, final long position, final long length)\n    {\n        if (position < NULL_POSITION)\n        {\n            throw new IllegalArgumentException(\"invalid position: \" + position);\n        }\n\n        if (length < NULL_LENGTH)\n        {\n            throw new IllegalArgumentException(\"invalid length: \" + length);\n        }\n\n        this.archiveDir = archiveDir;\n        this.termLength = recordingSummary.termBufferLength;\n        this.segmentLength = recordingSummary.segmentFileLength;\n        this.recordingId = recordingSummary.recordingId;\n\n        final long startPosition = recordingSummary.startPosition;\n        final long fromPosition = position == NULL_POSITION ? startPosition : position;\n        final long maxLength = recordingSummary.stopPosition != NULL_POSITION ?\n            recordingSummary.stopPosition - fromPosition : Long.MAX_VALUE - fromPosition;\n\n        final long replayLength = length == NULL_LENGTH ? maxLength : Math.min(length, maxLength);","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-archive/src/main/java/io/aeron/archive/RecordingReader.java#L47-L83","documentation":"RecordingReader validates replay parameters against the recording's metadata. A position below NULL_POSITION (i.e. a negative sentinel misuse) is not a valid replay start, so an IllegalArgumentException is thrown at construction time.","triggerScenarios":"Constructing RecordingReader (via the archive conductor's replay path) with position < Aeron.NULL_VALUE, e.g. passing -2/-3 or a miscomputed sentinel instead of NULL_POSITION (-1) to mean 'replay from start'.","commonSituations":"Client passes a negative replay position in a replay request; arithmetic bug computing start position; confusing NULL_POSITION with other Aeron sentinels like NULL_VALUE.","solutions":["Pass Aeron.NULL_POSITION (-1) to mean 'from the recording start', not arbitrary negative numbers.","Validate/clamp the requested replay position client-side before sending the replay request.","Check the code computing the position for sign or sentinel confusion.","Log the requested recordingId and position to identify the bad caller."],"exampleFix":"// before\nlong position = -2; // intended 'from start'\n// after\nlong position = Aeron.NULL_POSITION; // -1 means replay from start","handlingStrategy":"validation","validationCode":"if (position != Aeron.NULL_POSITION && position < 0) {\n    throw new IllegalArgumentException(\"position must be Aeron.NULL_POSITION or >= 0\");\n}","typeGuard":null,"tryCatchPattern":"try { replay(recId, position, length); }\ncatch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"invalid position\")) { fixSentinelAndRetry(); }\n}","preventionTips":["Always use Aeron.NULL_POSITION for 'replay from start'.","Sanitize replay positions from external inputs before sending requests.","Unit-test replay parameter handling with sentinel values."],"tags":["replay","invalid-argument","archive","position"],"backgroundTag":"invalid-argument-value","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}