{"record":{"id":"b89838c37f395db3","repo":"aeron-io/aeron","slug":"publication-is-closed-consensuspublisher","errorCode":null,"errorMessage":"publication is closed","messagePattern":"publication is closed","errorType":"exception","errorClass":"ClusterException","httpStatus":null,"severity":"error","filePath":"aeron-cluster/src/main/java/io/aeron/cluster/ConsensusPublisher.java","lineNumber":624,"sourceCode":"                .timestamp(entry.timestamp)\n                .serviceId(entry.serviceId)\n                .archiveEndpoint(archiveEndpoint);\n        }\n\n        standbySnapshotEncoder\n            .responseChannel(responseChannel)\n            .putEncodedCredentials(encodedCredentials, 0, encodedCredentials.length);\n\n        final int encodedLength = MessageHeaderEncoder.ENCODED_LENGTH + standbySnapshotEncoder.encodedLength();\n\n        return sendPublication(publication, buffer, encodedLength);\n    }\n\n    private static void checkResult(final long position, final Publication publication)\n    {\n        if (Publication.CLOSED == position)\n        {\n            throw new ClusterException(\"publication is closed\");\n        }\n\n        if (Publication.MAX_POSITION_EXCEEDED == position)\n        {\n            throw new ClusterException(\"publication at max position: term-length=\" + publication.termBufferLength());\n        }\n    }\n\n    private static boolean sendPublication(\n        final ExclusivePublication publication,\n        final ExpandableArrayBuffer buffer,\n        final int length)\n    {\n        int attempts = SEND_ATTEMPTS;\n        do\n        {\n            final long position = publication.offer(buffer, 0, length);\n            if (position > 0)","sourceCodeStart":606,"sourceCodeEnd":642,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-cluster/src/main/java/io/aeron/cluster/ConsensusPublisher.java#L606-L642","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Guard publication lifetime so it is closed only after consensus sends for that member stop","Upgrade to a newer Aeron version where election teardown races were fixed","Restart the affected member so it re-establishes consensus publications","Check logs for the election/member-removal event that closed the publication concurrently"],"exampleFix":"// before: closing a member's publication during an active election\npublication.close();\npublisher.commitPosition(...); // ClusterException: publication is closed\n// after\nif (!publication.isClosed()) {\n    publisher.commitPosition(...);\n}\npublication.close();","handlingStrategy":"try-catch","validationCode":"// Check publication liveness before consensus sends\nif (publication.isClosed()) { /* re-establish or stop sending */ }","typeGuard":null,"tryCatchPattern":"try {\n    publisher.commitPosition(...);\n} catch (ClusterException e) {\n    if (\"publication is closed\".equals(e.getMessage())) {\n        // re-create publications / let election restart member roles\n    } else { throw e; }\n}","preventionTips":["Serialize publication close with consensus send activity","Avoid closing member publications mid-election","Keep Aeron updated for teardown race fixes"],"tags":["aeron","cluster","publication","closed-resource"],"backgroundTag":"broken-pipe","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}