{"record":{"id":"830a0ea007d958fb","repo":"aeron-io/aeron","slug":"aeroncluster-context-ingressendpoints-must-be-null-when","errorCode":null,"errorMessage":"AeronCluster.Context ingressEndpoints must be null when using IPC ingress","messagePattern":"AeronCluster\\.Context ingressEndpoints must be null when using IPC ingress","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"aeron-cluster/src/main/java/io/aeron/cluster/client/AeronCluster.java","lineNumber":1487,"sourceCode":"         * Conclude configuration by setting up defaults when specifics are not provided.\n         */\n        public void conclude()\n        {\n            if ((boolean)IS_CONCLUDED_VH.getAndSet(this, true))\n            {\n                throw new ConcurrentConcludeException();\n            }\n\n            if (Strings.isEmpty(ingressChannel))\n            {\n                throw new ConfigurationException(\"ingressChannel must be specified\");\n            }\n\n            if (ingressChannel.startsWith(CommonContext.IPC_CHANNEL))\n            {\n                if (null != ingressEndpoints)\n                {\n                    throw new ConfigurationException(\n                        \"AeronCluster.Context ingressEndpoints must be null when using IPC ingress\");\n                }\n            }\n\n            if (Strings.isEmpty(egressChannel))\n            {\n                throw new ConfigurationException(\"egressChannel must be specified\");\n            }\n\n            final ChannelUri egressChannelUri = ChannelUri.parse(egressChannel);\n            if (egressChannelUri.isUdp())\n            {\n                egressChannelUri.put(REJOIN_PARAM_NAME, \"false\");\n                egressChannel = egressChannelUri.toString();\n            }\n\n            if (clientName.length() > Aeron.Configuration.MAX_CLIENT_NAME_LENGTH)\n            {","sourceCodeStart":1469,"sourceCodeEnd":1505,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-cluster/src/main/java/io/aeron/cluster/client/AeronCluster.java#L1469-L1505","documentation":"When ingressChannel is the IPC channel (aeron:ipc), ingress must go over shared memory to the co-located cluster node, so per-member ingressEndpoints cannot be used. Context.conclude() throws ConfigurationException if both IPC ingress and a non-null ingressEndpoints map are set, since they are mutually exclusive.","triggerScenarios":"Setting ctx.ingressChannel(\"aeron:ipc\") while ctx.ingressEndpoints(...) is non-null, then calling AeronCluster.connect()/conclude().","commonSituations":"Switching a remote-client config to IPC for local testing without clearing previously-set ingressEndpoints; merge of two configs that each set one of the two options.","solutions":["Remove the ctx.ingressEndpoints(...) call when using aeron:ipc","Or change ingressChannel to a UDP channel (aeron:udp?...) if you actually need remote member endpoints"],"exampleFix":"// before\nctx.ingressChannel(\"aeron:ipc\").ingressEndpoints(\"0=localhost:20001,1=localhost:20002\");\n// after\nctx.ingressChannel(\"aeron:ipc\"); // ingressEndpoints must be null for IPC","handlingStrategy":"validation","validationCode":"if (ctx.ingressChannel() != null && ctx.ingressChannel().startsWith(\"aeron:ipc\")\n    && ctx.ingressEndpoints() != null) {\n    throw new IllegalArgumentException(\"ingressEndpoints must be null when ingressChannel is aeron:ipc\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Centralize Context construction so IPC vs UDP ingress is a single, explicit switch","When switching to IPC for tests, explicitly clear ingressEndpoints (set null)"],"tags":["configuration","ipc","validation"],"backgroundTag":"mutually-exclusive-options","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"}