aeron-io/aeron · error · ArchiveException
response for correlationId=
Error message
response for correlationId=<correlationId>, error: <errorMessage>
What it means
ArchiveException raised when the archive replies with an ERROR control response for the awaited correlationId and the error code is not the single allowedErrorCode the caller tolerates. The message embeds the poller's errorMessage from the archive and the exception carries the archive error code and correlationId.
Solutions
- Read e.errorCode() and the embedded archive errorMessage to identify the archive-side failure.
- Check that the target recordingId exists and is not concurrently locked by another archive operation.
- If the error code is expected in your workflow, catch it explicitly and treat it as success (as the allowedErrorCode mechanism does).
- Re-establish the archive session if the error indicates an invalid or expired control session.
Example fix
// before
archive.purgeSegments(recordingId, newStartPosition);
// after
try {
archive.purgeSegments(recordingId, newStartPosition);
} catch (ArchiveException e) {
if (e.errorCode() == ArchiveException.UNKNOWN_RECORDING) {
return; // already gone - treat as success
}
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
// confirm recording exists and no concurrent operation is in flight long count = archive.getStopPosition(recordingId); // surfaces UNKNOWN_RECORDING early
Try / catch
try {
archive.truncateRecording(recordingId, position);
} catch (ArchiveException e) {
if (e.errorCode() == ArchiveException.UNKNOWN_RECORDING) { /* already deleted */ }
else if (e.errorCode() == ArchiveException.ACTIVE_LISTING) { /* retry later */ }
else throw e;
} Prevention
- Check recording existence before destructive operations.
- Serialize archive mutations per recording to avoid concurrent-operation errors.
- Match expected error codes via the allowedErrorCode mechanism rather than ad-hoc catches.
When it happens
Trigger: Calling pollForResponse(invokerType, correlationId, allowedErrorCode) style awaits (e.g. truncate/purge allowing NULL_SESSION) when the archive returns any other error code, such as UNKNOWN_RECORDING, GENERIC, or ACTIVE_LISTING.
Common situations: Deleting or truncating a recording that no longer exists; concurrent archive operations on the same recording; catalog errors on the archive; a session invalidated between requests.
Related errors
- failed get acknowledgement of replay request to: " +…
- (int)poller.relevantId()
- unexpected response code
- ACTIVE_RECORDING
- aeronArchiveContext must be set
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/368e4618445ea954.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-archive/src/main/java/io/aeron/archive/client/AeronArchive.java:2477
if (poller.controlSessionId() != controlSessionId)
{
context.runInvokers();
continue;
}
final ControlResponseCode code = poller.code();
if (ControlResponseCode.ERROR == code)
{
final long relevantId = poller.relevantId();
if (poller.correlationId() == correlationId)
{
if (relevantId == allowedErrorCode)
{
return false;
}
throw new ArchiveException(
"response for correlationId=" + correlationId + ", error: " + poller.errorMessage(),
(int)relevantId,
poller.correlationId());
}
else if (context.errorHandler() != null)
{
context.errorHandler().onError(new ArchiveException(
"response for correlationId=" + correlationId + ", error: " + poller.errorMessage(),
(int)relevantId,
poller.correlationId()));
}
}
else if (poller.correlationId() == correlationId)
{
if (ControlResponseCode.OK != code)
{
throw new ArchiveException("unexpected response code: " + code);
}View on GitHub (pinned to 6d60124e15)