{"record":{"id":"1a8ce8404a825dca","repo":"aeron-io/aeron","slug":"option-conflicts-with-existing-subscription-rejoin-isrejoin","errorCode":null,"errorMessage":"option conflicts with existing subscription: rejoin=${isRejoin} existingChannel=${existingChannel} channel=${channel}","messagePattern":"option conflicts with existing subscription: rejoin=(.+?) existingChannel=(.+?) channel=(.+?)","errorType":"exception","errorClass":"InvalidChannelException","httpStatus":null,"severity":"error","filePath":"aeron-driver/src/main/java/io/aeron/driver/DriverConductor.java","lineNumber":1630,"sourceCode":"            validateUdpChannelAgainstReceiveChannelEndpoint(params, udpChannel, channelEndpoint);\n\n            for (final SubscriptionLink subscription : subscriptionLinks)\n            {\n                final boolean matchesTag = !udpChannel.hasTag() || channelEndpoint.matchesTag(udpChannel);\n\n                if (matchesTag && subscription.matches(channelEndpoint, streamId, params))\n                {\n                    if (params.isReliable != subscription.isReliable())\n                    {\n                        throw new InvalidChannelException(\n                            \"option conflicts with existing subscription: reliable=\" + params.isReliable +\n                                \" existingChannel=\" + subscription.channel() + \" channel=\" +\n                                udpChannel.originalUriString());\n                    }\n\n                    if (params.isRejoin != subscription.isRejoin())\n                    {\n                        throw new InvalidChannelException(\n                            \"option conflicts with existing subscription: rejoin=\" + params.isRejoin +\n                                \" existingChannel=\" + subscription.channel() + \" channel=\" +\n                                udpChannel.originalUriString());\n                    }\n\n                    if (params.isResponse != subscription.isResponse())\n                    {\n                        throw new InvalidChannelException(\n                            \"option conflicts with existing subscription: isResponse=\" + params.isResponse +\n                                \" existingChannel=\" + subscription.channel() + \" channel=\" +\n                                udpChannel.originalUriString());\n                    }\n                }\n            }\n        }\n    }\n\n    private void linkMatchingImages(final SubscriptionLink subscriptionLink)","sourceCodeStart":1612,"sourceCodeEnd":1648,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-driver/src/main/java/io/aeron/driver/DriverConductor.java#L1612-L1648","documentation":"Subscriptions that share a channel endpoint and streamId in one Aeron client must also agree on the 'rejoin' option (whether a lost image re-joins after going unavailable). The driver throws this InvalidChannelException when a new subscription matches an existing one (channel endpoint, streamId, tag) but sets a different rejoin value.","triggerScenarios":"Calling Aeron.addSubscription with a URI whose rejoin=true/false differs from an existing matching subscription on the same endpoint/streamId, e.g. adding \"aeron:udp?endpoint=h:40456|rejoin=true\" when \"...|rejoin=false\" is already subscribed.","commonSituations":"Mixing default (rejoin=true) with an explicitly disabled rejoin URI; gradual migration where one component sets rejoin=false for stable streams and another uses defaults; duplicated subscribe logic with divergent tuning flags.","solutions":["Use the same rejoin value for all subscriptions on the same channel/streamId","Close the existing conflicting subscription before adding the new one","Separate the conflicting subscriptions onto different streams or channels with distinct endpoints","Standardize URI templates application-wide for reliability/rejoin tuning"],"exampleFix":"// before\naeron.addSubscription(\"aeron:udp?endpoint=localhost:40456|rejoin=true\", 1001);\n// after (match existing)\naeron.addSubscription(\"aeron:udp?endpoint=localhost:40456|rejoin=false\", 1001);","handlingStrategy":"try-catch","validationCode":"boolean rejoin = Boolean.parseBoolean(uriParam(channel, \"rejoin\", \"true\"));\n// ensure all subscriptions on this endpoint/streamId use the same rejoin value","typeGuard":null,"tryCatchPattern":"try { aeron.addSubscription(channel, streamId, handler, unavailableHandler); } catch (InvalidChannelException e) { if (e.getMessage().contains(\"rejoin=\")) { log.error(\"rejoin mismatch on {}: {}\", channel, e.getMessage()); } throw e; }","preventionTips":["Set rejoin explicitly (same value) in every URI for a shared stream","Avoid mixing default rejoin with explicit rejoin=false URIs","Use distinct streamIds when different rejoin semantics are required","Keep channel config in shared constants"],"tags":["aeron","subscription","channel-config","conflict"],"backgroundTag":"conflicting-config-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"}