aeron-io/aeron · error · ArchiveException
errorCode (variable)
errorCode (variable)
Error message
errorMessage + ", recordingId=" + recordingId + ", replaySessionId=" + sessionId + ", segmentFile=" + segmentFileName(recordingId, segmentFileBasePosition)
What it means
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.
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
Example fix
// before: replay from an unvalidated position archive.startReplay(recordingId, requestedPosition, length); // after: validate against the recording descriptor first RecordingDescriptor d = archive.listRecording(recordingId); long pos = Math.max(requestedPosition, d.startPosition()); long len = Math.min(length, d.stopPosition() - pos); archive.startReplay(recordingId, pos, len);
Defensive patterns
Strategy: try-catch
Validate before calling
RecordingDescriptor d = archive.listRecording(recordingId);
if (replayPosition < d.startPosition() || replayPosition > d.stopPosition()) {
throw new IllegalArgumentException("replay position out of range: " + replayPosition);
} Type guard
static boolean replayPositionValid(RecordingDescriptor d, long position, long length) {
return position >= d.startPosition() && position + length <= d.stopPosition();
} Try / catch
try {
replaySubscription = archive.startReplay(recordingId, position, length, replayChannel, replayStreamId);
} catch (ArchiveException e) {
if (e.getMessage().contains("replaySessionId=")) {
// parse errorCode and segmentFile from message; clamp position or wait for recording progress
retryReplayWithAdjustedPosition(e.errorCode());
} else { throw e; }
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- invalid position: " + position
- invalid length: " + length
- length must be positive
- fromPosition + " position not aligned to valid fragment
- failed to open recording segment file " + segmentFileName
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/56d83f553fd1b9f3.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-archive/src/main/java/io/aeron/archive/ReplaySession.java:541
}
position += bytesRead;
}
while (byteBuffer.remaining() > 0);
return limit;
}
private void raiseError(final String errorMessage, final int errorCode, final Throwable cause)
{
revokePublication = true;
this.errorCode = errorCode;
this.errorMessage = errorMessage +
", recordingId=" + recordingId +
", replaySessionId=" + sessionId +
", segmentFile=" + segmentFileName(recordingId, segmentFileBasePosition);
state(State.INACTIVE, errorMessage);
throw new ArchiveException(this.errorMessage, cause, errorCode);
}
private boolean notExtended(final long replayPosition, final long oldStopPosition)
{
final Counter limitPosition = this.limitPosition;
final long currentLimitPosition = limitPosition.get();
long newStopPosition = oldStopPosition;
if (limitPosition.isClosed())
{
if (countersReader.getCounterRegistrationId(limitPosition.id()) == limitPosition.registrationId())
{
replayLimit = currentLimitPosition;
newStopPosition = Math.max(oldStopPosition, currentLimitPosition);
}
else if (replayLimit >= oldStopPosition)
{
replayLimit = oldStopPosition;View on GitHub (pinned to 6d60124e15)