{"record":{"id":"56d83f553fd1b9f3","repo":"aeron-io/aeron","slug":"errorcode-variable","errorCode":"errorCode (variable)","errorMessage":"errorMessage + \", recordingId=\" + recordingId + \", replaySessionId=\" + sessionId + \", segmentFile=\" + segmentFileName(recordingId, segmentFileBasePosition)","messagePattern":"errorMessage \\+ \", recordingId=\" \\+ recordingId \\+ \", replaySessionId=\" \\+ sessionId \\+ \", segmentFile=\" \\+ segmentFileName\\(recordingId, segmentFileBasePosition\\)","errorType":"exception","errorClass":"ArchiveException","httpStatus":null,"severity":"error","filePath":"aeron-archive/src/main/java/io/aeron/archive/ReplaySession.java","lineNumber":541,"sourceCode":"            }\n\n            position += bytesRead;\n        }\n        while (byteBuffer.remaining() > 0);\n\n        return limit;\n    }\n\n    private void raiseError(final String errorMessage, final int errorCode, final Throwable cause)\n    {\n        revokePublication = true;\n        this.errorCode = errorCode;\n        this.errorMessage = errorMessage +\n            \", recordingId=\" + recordingId +\n            \", replaySessionId=\" + sessionId +\n            \", segmentFile=\" + segmentFileName(recordingId, segmentFileBasePosition);\n        state(State.INACTIVE, errorMessage);\n        throw new ArchiveException(this.errorMessage, cause, errorCode);\n    }\n\n    private boolean notExtended(final long replayPosition, final long oldStopPosition)\n    {\n        final Counter limitPosition = this.limitPosition;\n        final long currentLimitPosition = limitPosition.get();\n        long newStopPosition = oldStopPosition;\n\n        if (limitPosition.isClosed())\n        {\n            if (countersReader.getCounterRegistrationId(limitPosition.id()) == limitPosition.registrationId())\n            {\n                replayLimit = currentLimitPosition;\n                newStopPosition = Math.max(oldStopPosition, currentLimitPosition);\n            }\n            else if (replayLimit >= oldStopPosition)\n            {\n                replayLimit = oldStopPosition;","sourceCodeStart":523,"sourceCodeEnd":559,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-archive/src/main/java/io/aeron/archive/ReplaySession.java#L523-L559","documentation":"ReplaySession.raiseError is the central failure point for a replay session: it attaches the errorCode plus recordingId, replaySessionId and the current segment file name to the message, transitions the session to INACTIVE, and throws ArchiveException with the original cause. It is a generic error-raising path used by init, replay, doWork, verifyChecksum and openRecordingSegment, so the appended context is the key to diagnosing which stage failed.","triggerScenarios":"Any replay-session stage that validates state and calls raiseError: replay requested at an invalid position, replay length/position out of range, replaying a recording not extended to the requested stop position, a segment file missing or failing checksum verification, or a failed segment open. The concrete errorCode/cause on the ArchiveException identifies the sub-case.","commonSituations":"Client requests a replay from a position before the recording's startPosition or beyond its stopPosition; requesting replay of a still-active recording whose segments are not yet on disk; corrupted or partially written segment files causing checksum verification failures; using a stale sessionId after the replay session was already torn down.","solutions":["Read the full errorMessage (errorCode, recordingId, replaySessionId, segmentFile) to identify which replay stage failed and fix accordingly","If replay position was rejected, clamp the requested position/replayLength to the recording descriptor's startPosition/stopPosition obtained from the archive","If a segment file is missing/incomplete, wait for recording to progress (or stop) before replaying, and verify the archive directory is intact","Check archive logs and disk integrity for the named segment file; restore or re-record if the file is corrupt"],"exampleFix":"// before: replay from an unvalidated position\narchive.startReplay(recordingId, requestedPosition, length);\n\n// after: validate against the recording descriptor first\nRecordingDescriptor d = archive.listRecording(recordingId);\nlong pos = Math.max(requestedPosition, d.startPosition());\nlong len = Math.min(length, d.stopPosition() - pos);\narchive.startReplay(recordingId, pos, len);","handlingStrategy":"try-catch","validationCode":"RecordingDescriptor d = archive.listRecording(recordingId);\nif (replayPosition < d.startPosition() || replayPosition > d.stopPosition()) {\n    throw new IllegalArgumentException(\"replay position out of range: \" + replayPosition);\n}","typeGuard":"static boolean replayPositionValid(RecordingDescriptor d, long position, long length) {\n    return position >= d.startPosition() && position + length <= d.stopPosition();\n}","tryCatchPattern":"try {\n    replaySubscription = archive.startReplay(recordingId, position, length, replayChannel, replayStreamId);\n} catch (ArchiveException e) {\n    if (e.getMessage().contains(\"replaySessionId=\")) {\n        // parse errorCode and segmentFile from message; clamp position or wait for recording progress\n        retryReplayWithAdjustedPosition(e.errorCode());\n    } else { throw e; }\n}","preventionTips":["Always fetch the recording descriptor and clamp replay position/length to startPosition..stopPosition before requesting a replay","For live replays, subscribe from a position within recorded data and handle progression incrementally","Keep the archive directory intact; never delete or edit segment files of active recordings","Correlate failures using the recordingId/replaySessionId/segmentFile fields embedded in the error message"],"tags":["archive","replay","session-lifecycle","positioning"],"backgroundTag":"invalid-state-transition","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"}