aeron-io/aeron · error · ClusterException

publication at max position: term-length=

Error message

publication at max position: term-length=${termBufferLength}

What it means

checkResult throws when a publication offer returns MAX_POSITION_EXCEEDED. The term buffer for the consensus publication is full at its maximum position, meaning consumers stopped draining it far behind the producer position.

Solutions

  1. Fix or restart the member whose consensus subscription is not consuming
  2. Increase consensus channel term length (term-length URI param) if flow control demands it
  3. Enable/rely on flow control (min/min-ticks) so the leader does not outrun the slowest member indefinitely
  4. Verify network connectivity and that the follower is not blocked (disk, GC)

Example fix

// before: leader outrunning a stalled follower
ClusterException: publication at max position: term-length=65536
// after
AeronCluster consensus channel URI: aeron:udp?endpoint=...|term-length=1m|fc=min
Defensive patterns

Strategy: retry

Validate before calling

// Monitor consumer position vs producer position before sending
if (publication.position() - publication.consumerPosition() > threshold) { /* back off, investigate subscriber */ }

Try / catch

try {
    publisher.appendPosition(...);
} catch (ClusterException e) {
    if (e.getMessage().startsWith("publication at max position")) {
        // restart the stalled member, then re-offer with backoff
    } else { throw e; }
}

Prevention

When it happens

Trigger: offer(...) on any consensus publication (canvassPosition, requestVote, placeVote, newLeadershipTerm, appendPosition, commitPosition) returns Publication.MAX_POSITION_EXCEEDED — the publication's image reached its max position because subscribers (peer members) are not consuming.

Common situations: A peer cluster member stalled or dead so nobody drains its consensus subscription; term buffer length too small for message volume; long GC pauses on a follower letting positions run away.

Related errors


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

Appendix: source

Thrown at aeron-cluster/src/main/java/io/aeron/cluster/ConsensusPublisher.java:629

        standbySnapshotEncoder
            .responseChannel(responseChannel)
            .putEncodedCredentials(encodedCredentials, 0, encodedCredentials.length);

        final int encodedLength = MessageHeaderEncoder.ENCODED_LENGTH + standbySnapshotEncoder.encodedLength();

        return sendPublication(publication, buffer, encodedLength);
    }

    private static void checkResult(final long position, final Publication publication)
    {
        if (Publication.CLOSED == position)
        {
            throw new ClusterException("publication is closed");
        }

        if (Publication.MAX_POSITION_EXCEEDED == position)
        {
            throw new ClusterException("publication at max position: term-length=" + publication.termBufferLength());
        }
    }

    private static boolean sendPublication(
        final ExclusivePublication publication,
        final ExpandableArrayBuffer buffer,
        final int length)
    {
        int attempts = SEND_ATTEMPTS;
        do
        {
            final long position = publication.offer(buffer, 0, length);
            if (position > 0)
            {
                return true;
            }

            checkResult(position, publication);

View on GitHub (pinned to 6d60124e15)