{"record":{"id":"a81d55f98f10b0cd","repo":"aeron-io/aeron","slug":"offer-failed-due-to-max-position-being-reached-term-length","errorCode":null,"errorMessage":"offer failed due to max position being reached: term-length=","messagePattern":"offer failed due to max position being reached: term-length=","errorType":"exception","errorClass":"ArchiveException","httpStatus":null,"severity":"error","filePath":"aeron-archive/src/main/java/io/aeron/archive/client/ArchiveProxy.java","lineNumber":1493,"sourceCode":"            final long position = publication.offer(buffer, 0, MessageHeaderEncoder.ENCODED_LENGTH + length);\n            if (position > 0)\n            {\n                return true;\n            }\n\n            if (position == Publication.CLOSED)\n            {\n                throw new ArchiveException(\"connection to the archive has been closed\");\n            }\n\n            if (position == Publication.NOT_CONNECTED)\n            {\n                throw new ArchiveException(\"connection to the archive is no longer available\");\n            }\n\n            if (position == Publication.MAX_POSITION_EXCEEDED)\n            {\n                throw new ArchiveException(\n                    \"offer failed due to max position being reached: term-length=\" + publication.termBufferLength());\n            }\n\n            if (--attempts <= 0)\n            {\n                return false;\n            }\n\n            retryIdleStrategy.idle();\n        }\n    }\n\n    private boolean offerWithTimeout(final int length, final AgentInvoker aeronClientInvoker)\n    {\n        retryIdleStrategy.reset();\n\n        final long deadlineNs = nanoClock.nanoTime() + connectTimeoutNs;\n        while (true)","sourceCodeStart":1475,"sourceCodeEnd":1511,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-archive/src/main/java/io/aeron/archive/client/ArchiveProxy.java#L1475-L1511","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Close the archive session and create a new archive client connection (a fresh publication resets the position)","Increase term-length on the control channel so the publication cannot exhaust its position range quickly","Reduce control-command frequency (e.g. avoid tight polling/keepAlive loops)","Report/investigate if this occurs early in a session's life — it indicates a misconfigured publication"],"exampleFix":"// before\nChannelUriStringBuilder builder = new ChannelUriStringBuilder()\n    .media(\"udp\").termLength(64 * 1024); // tiny term length, exhausts quickly\n\n// after\nbuilder.termLength(1024 * 1024); // larger term buffer on the control channel","handlingStrategy":"fallback","validationCode":"// not practically detectable pre-call; monitor position growth\nif (controlPublication.position() > Long.MAX_VALUE - termLength) { renewSession(); }","typeGuard":null,"tryCatchPattern":"try {\n    archiveProxy.stopRecording(recordingId);\n} catch (ArchiveException e) {\n    if (e.getMessage().contains(\"max position\")) {\n        renewArchiveSession(); // only recovery: new publication resets position\n    }\n}","preventionTips":["Use a sane term-length on the control channel (default, not shrunken)","Avoid pathological command rates against a single long-lived control publication","Recycle archive client sessions in very long-running services","Treat this error as terminal for the publication; do not retry in place"],"tags":["aeron-archive","publication","term-buffer","overflow"],"backgroundTag":"value-out-of-range","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}