{"record":{"id":"2b999395e3597d2c","repo":"aeron-io/aeron","slug":"publication-is-closed-consensusmoduleproxy","errorCode":null,"errorMessage":"publication is closed","messagePattern":"publication is closed","errorType":"console","errorClass":"ClusterException","httpStatus":null,"severity":"error","filePath":"aeron-cluster/src/main/java/io/aeron/cluster/service/ConsensusModuleProxy.java","lineNumber":228,"sourceCode":"\n            return true;\n        }\n\n        checkResult(position, publication);\n\n        return false;\n    }\n\n    private static void checkResult(final long position, final Publication publication)\n    {\n        if (Publication.NOT_CONNECTED == position)\n        {\n            throw new ClusterException(\"publication is not connected\");\n        }\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","sourceCodeStart":210,"sourceCodeEnd":237,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-cluster/src/main/java/io/aeron/cluster/service/ConsensusModuleProxy.java#L210-L237","documentation":"ConsensusModuleProxy.checkResult throws this when a publication operation returns Publication.CLOSED, meaning the publication to the consensus module has been closed (e.g. during shutdown or after an error). Further offers via scheduleTimer/cancelTimer/offer/tryClaim/ack/closeSession cannot succeed.","triggerScenarios":"Invoking any ConsensusModuleProxy method (scheduleTimer, cancelTimer, offer, tryClaim, ack, closeSession) after the consensus module publication was closed, typically during orderly or abnormal cluster shutdown.","commonSituations":"Service continuing to ack or schedule timers after container shutdown begun; consensus module crashed and closed the channel; close() raced with an in-flight agent duty cycle call.","solutions":["Stop using the proxy once the container/service is closing; guard calls with an isClosing/isShutdown flag.","Treat this as terminal: rethrow or log and end the service duty cycle rather than retrying.","Verify shutdown ordering: close ClusteredServiceAgent before closing publications it uses.","Check for a root cause that closed the publication (e.g. earlier ClusterException in the consensus module log)."],"exampleFix":"// before\nproxy.ack(logPosition, timestamp, sessionId, serviceId);\n// after\nif (!isClosing && !proxy.ack(logPosition, timestamp, sessionId, serviceId)) {\n    // handle not-offered/closed\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    proxy.ack(logPosition, timestamp, sessionId, serviceId);\n} catch (ClusterException e) {\n    if (e.getMessage().contains(\"publication is closed\")) {\n        // terminal: stop issuing calls, initiate shutdown/cleanup\n    } else {\n        throw e;\n    }\n}","preventionTips":["Guard all proxy calls with a container isClosing flag.","Close services before publications to avoid use-after-close races.","Investigate and fix the root cause that closed the publication (check consensus module logs)."],"tags":["aeron","publication","closed","cluster"],"backgroundTag":"invalid-state-transition","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}