aeron-io/aeron · error · ClusterException

publication is closed

Error message

publication is closed

What it means

checkResult in ConsensusPublisher throws when a Publication returns the CLOSED sentinel. The consensus publication (to a cluster member's consensus channel) was closed while the publisher still tried to send on it, so sending can no longer proceed.

Solutions

  1. Guard publication lifetime so it is closed only after consensus sends for that member stop
  2. Upgrade to a newer Aeron version where election teardown races were fixed
  3. Restart the affected member so it re-establishes consensus publications
  4. Check logs for the election/member-removal event that closed the publication concurrently

Example fix

// before: closing a member's publication during an active election
publication.close();
publisher.commitPosition(...); // ClusterException: publication is closed
// after
if (!publication.isClosed()) {
    publisher.commitPosition(...);
}
publication.close();
Defensive patterns

Strategy: try-catch

Validate before calling

// Check publication liveness before consensus sends
if (publication.isClosed()) { /* re-establish or stop sending */ }

Try / catch

try {
    publisher.commitPosition(...);
} catch (ClusterException e) {
    if ("publication is closed".equals(e.getMessage())) {
        // re-create publications / let election restart member roles
    } else { throw e; }
}

Prevention

When it happens

Trigger: Any of canvassPosition, requestVote, placeVote, newLeadershipTerm, appendPosition, commitPosition publishing after the underlying ExclusivePublication was closed — e.g. after member removal, role change, or election teardown closing publications while messages are still in flight.

Common situations: Election completing and closing loser publications concurrently with heartbeat/vote sends; shutting down a node while the leader still commits positions to it; aeron client close racing consensus traffic.

Related errors


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

Appendix: source

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

                .timestamp(entry.timestamp)
                .serviceId(entry.serviceId)
                .archiveEndpoint(archiveEndpoint);
        }

        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)

View on GitHub (pinned to 6d60124e15)