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

  1. Read e.errorCode() and the embedded archive errorMessage to identify the archive-side failure.
  2. Check that the target recordingId exists and is not concurrently locked by another archive operation.
  3. If the error code is expected in your workflow, catch it explicitly and treat it as success (as the allowedErrorCode mechanism does).
  4. 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

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


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)