{"record":{"id":"7098eda18caf5bd0","repo":"aeron-io/aeron","slug":"aeron-client-must-use-conductor-agent-invoker-7098ed","errorCode":null,"errorMessage":"Aeron client must use conductor agent invoker","messagePattern":"Aeron client must use conductor agent invoker","errorType":"validation","errorClass":"ClusterException","httpStatus":null,"severity":"error","filePath":"aeron-cluster/src/main/java/io/aeron/cluster/ConsensusModule.java","lineNumber":1915,"sourceCode":"                        clusterId,\n                        ConsensusModuleVersion.VERSION,\n                        ConsensusModuleVersion.GIT_SHA);\n                }\n            }\n\n            if (null == ingressChannel)\n            {\n                throw new ClusterException(\"ingressChannel must be specified\");\n            }\n\n            if (!(aeron.context().subscriberErrorHandler() instanceof RethrowingErrorHandler))\n            {\n                throw new ClusterException(\"Aeron client must use a RethrowingErrorHandler\");\n            }\n\n            if (!aeron.context().useConductorAgentInvoker())\n            {\n                throw new ClusterException(\"Aeron client must use conductor agent invoker\");\n            }\n\n            if (null == errorCounter)\n            {\n                throw new ClusterException(\"error counter must be supplied if aeron client is\");\n            }\n\n            if (null == countedErrorHandler)\n            {\n                countedErrorHandler = new CountedErrorHandler(errorHandler, errorCounter);\n                if (ownsAeronClient)\n                {\n                    aeron.context().errorHandler(countedErrorHandler);\n                }\n            }\n\n            if (null == moduleStateCounter)\n            {","sourceCodeStart":1897,"sourceCodeEnd":1933,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-cluster/src/main/java/io/aeron/cluster/ConsensusModule.java#L1897-L1933","documentation":"The cluster drives the Aeron client from its consensus agent loop, so conclude() requires the client to be configured with useConductorAgentInvoker(true) — the client's conductor must run inside the cluster thread rather than on its own thread. A shared client using its own conductor thread is rejected with a ClusterException.","triggerScenarios":"Passing a pre-created Aeron client (ctx.aeron(client)) whose Aeron.Context was not built with useConductorAgentInvoker(true).","commonSituations":"Reusing the application's standard Aeron client for the ConsensusModule; migrating from standalone Aeron usage to clustered; copying Aeron.connect code from non-cluster examples.","solutions":["Create a dedicated client for the cluster: Aeron.connect(new Aeron.Context().useConductorAgentInvoker(true)...)","Or omit ctx.aeron(...) so the ConsensusModule constructs a compliant client itself","If sharing is required, ensure invoker mode is on and invoke aeron.conductorAgentInvoker().invoke() from the cluster thread"],"exampleFix":"// before\nAeron aeron = Aeron.connect(new Aeron.Context());\nctx.aeron(aeron); // own conductor thread\n// after\nAeron aeron = Aeron.connect(new Aeron.Context()\n    .useConductorAgentInvoker(true));\nctx.aeron(aeron);","handlingStrategy":"validation","validationCode":"if (!aeron.context().useConductorAgentInvoker()) {\n    throw new IllegalStateException(\"shared Aeron client must be created with useConductorAgentInvoker(true)\");\n}","typeGuard":"boolean usesAgentInvoker(Aeron aeron) { return aeron.context().useConductorAgentInvoker(); }","tryCatchPattern":"try { ctx.conclude(); } catch (ClusterException e) { if (e.getMessage().contains(\"conductor agent invoker\")) { /* recreate client in invoker mode */ } }","preventionTips":["Always Aeron.connect(new Aeron.Context().useConductorAgentInvoker(true)) for cluster clients","Don't reuse the app's thread-based Aeron client in the ConsensusModule","Remember invoker-mode clients must be driven from the cluster agent thread"],"tags":["configuration","threading","aeron-client"],"backgroundTag":"invalid-config-value","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"}