aeron-io/aeron · error · ArchiveException

offer failed due to max position being reached: term-length=

Error message

offer failed due to max position being reached: term-length=

What it means

ArchiveProxy.offer() throws this ArchiveException when the control publication's offer() returned Publication.MAX_POSITION_EXCEEDED, i.e. the publication's term buffer has reached the maximum possible position and cannot wrap further. The archive control channel cannot accept any more commands because its bounded position space is exhausted.

Solutions

  1. Close the archive session and create a new archive client connection (a fresh publication resets the position)
  2. Increase term-length on the control channel so the publication cannot exhaust its position range quickly
  3. Reduce control-command frequency (e.g. avoid tight polling/keepAlive loops)
  4. Report/investigate if this occurs early in a session's life — it indicates a misconfigured publication

Example fix

// before
ChannelUriStringBuilder builder = new ChannelUriStringBuilder()
    .media("udp").termLength(64 * 1024); // tiny term length, exhausts quickly

// after
builder.termLength(1024 * 1024); // larger term buffer on the control channel
Defensive patterns

Strategy: fallback

Validate before calling

// not practically detectable pre-call; monitor position growth
if (controlPublication.position() > Long.MAX_VALUE - termLength) { renewSession(); }

Try / catch

try {
    archiveProxy.stopRecording(recordingId);
} catch (ArchiveException e) {
    if (e.getMessage().contains("max position")) {
        renewArchiveSession(); // only recovery: new publication resets position
    }
}

Prevention

When it happens

Trigger: Any ArchiveProxy command (keepAlive, closeSession, startRecording, stopRecording, stopRecordingByIdentity, stopReplay) whose offer hits MAX_POSITION_EXCEEDED on a control publication with an extremely long-lived/overflowed position — effectively only on a control session that has sent an astronomical number of messages.

Common situations: A very long-running archive client whose control publication has exhausted its 64-bit position space due to a misconfigured (very small) term length combined with extremely high command volume; practically rare but fatal for the session.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12). Data as JSON: /api/errors/a81d55f98f10b0cd. Report an issue: GitHub.

Appendix: source

Thrown at aeron-archive/src/main/java/io/aeron/archive/client/ArchiveProxy.java:1493

            final long position = publication.offer(buffer, 0, MessageHeaderEncoder.ENCODED_LENGTH + length);
            if (position > 0)
            {
                return true;
            }

            if (position == Publication.CLOSED)
            {
                throw new ArchiveException("connection to the archive has been closed");
            }

            if (position == Publication.NOT_CONNECTED)
            {
                throw new ArchiveException("connection to the archive is no longer available");
            }

            if (position == Publication.MAX_POSITION_EXCEEDED)
            {
                throw new ArchiveException(
                    "offer failed due to max position being reached: term-length=" + publication.termBufferLength());
            }

            if (--attempts <= 0)
            {
                return false;
            }

            retryIdleStrategy.idle();
        }
    }

    private boolean offerWithTimeout(final int length, final AgentInvoker aeronClientInvoker)
    {
        retryIdleStrategy.reset();

        final long deadlineNs = nanoClock.nanoTime() + connectTimeoutNs;
        while (true)

View on GitHub (pinned to 6d60124e15)