{"record":{"id":"9adf7f4c33a26b03","repo":"aeron-io/aeron","slug":"existing-publication-has-different-mtu-length-existing","errorCode":null,"errorMessage":"existing publication has different 'mtu-length': existing={existingValue} requested={newValue} existingChannel={existingChannelUri} channel={newChannelUri}","messagePattern":"existing publication has different 'mtu-length': existing=(.+?) requested=(.+?) existingChannel=(.+?) channel=(.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"aeron-driver/src/main/java/io/aeron/driver/PublicationParams.java","lineNumber":301,"sourceCode":"        return \"existing publication has different '\" + paramName + \"': existing=\" +\n            existingValue + \" requested=\" + newValue + \" existingChannel=\" + existingChannelUri +\n            \" channel=\" + newChannelUri;\n    }\n\n    static void confirmMatch(\n        final ChannelUri channelUri,\n        final PublicationParams params,\n        final RawLog rawLog,\n        final int existingSessionId,\n        final String existingChannel,\n        final int existingInitialTermId,\n        final int existingTermId,\n        final int existingTermOffset)\n    {\n        final int mtuLength = LogBufferDescriptor.mtuLength(rawLog.metaData());\n        if (channelUri.containsKey(MTU_LENGTH_PARAM_NAME) && mtuLength != params.mtuLength)\n        {\n            throw new IllegalStateException(formatMatchError(\n                MTU_LENGTH_PARAM_NAME,\n                String.valueOf(mtuLength),\n                String.valueOf(params.mtuLength),\n                existingChannel,\n                channelUri.toString()));\n        }\n\n        if (channelUri.containsKey(TERM_LENGTH_PARAM_NAME) && rawLog.termLength() != params.termLength)\n        {\n            throw new IllegalStateException(formatMatchError(\n                TERM_LENGTH_PARAM_NAME,\n                String.valueOf(rawLog.termLength()),\n                String.valueOf(params.termLength),\n                existingChannel,\n                channelUri.toString()));\n        }\n\n        if (channelUri.containsKey(SESSION_ID_PARAM_NAME) && params.sessionId != existingSessionId)","sourceCodeStart":283,"sourceCodeEnd":319,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-driver/src/main/java/io/aeron/driver/PublicationParams.java#L283-L319","documentation":"When reusing an existing publication's log buffer (same stream on the same channel), the driver checks that any parameter explicitly present in the new channel URI matches the existing publication. PublicationParams.confirmMatch throws IllegalStateException when the URI specifies mtu-length but the existing log's MTU differs — Aeron will not silently re-configure a live publication.","triggerScenarios":"A second addPublication call on a channel URI containing mtu-length while an existing publication for the same channel/session already runs with a different MTU (existing log buffer mtuLength != params.mtuLength).","commonSituations":"Two parts of an app adding the 'same' publication with slightly different URIs (one with mtu-length=8k, one without or with 16k); reconfiguring MTU after restart while old publication lingers; test harness vs prod URI drift.","solutions":["Make the new channel URI identical to the existing one (same mtu-length) so publication reuse succeeds.","Remove mtu-length from the URI entirely; note the check only fires when the URI explicitly contains mtu-length.","Close the existing publication before adding one with the new MTU.","Canonicalize URIs in application code (parse with ChannelUri and compare params) before addPublication."],"exampleFix":"// before: conflicting MTU on reuse\naeron.addPublication(\"aeron:udp?endpoint=localhost:40456|mtu-length=8k\", 1001); // existing runs 16k\n\n// after\naeron.addPublication(\"aeron:udp?endpoint=localhost:40456|mtu-length=16k\", 1001);","handlingStrategy":"try-catch","validationCode":"ChannelUri uri = ChannelUri.parse(newChannel);\nString requestedMtu = uri.get(\"mtu-length\");\n// only compare when explicitly present; otherwise reuse succeeds\nif (requestedMtu != null && existingMtu != Integer.parseInt(requestedMtu)) {\n    newChannel = setParam(newChannel, \"mtu-length\", String.valueOf(existingMtu));\n}","typeGuard":null,"tryCatchPattern":"try {\n    pub = aeron.addPublication(channel, streamId);\n} catch (IllegalStateException e) {\n    if (e.getMessage().startsWith(\"existing publication has different 'mtu-length'\")) {\n        throw new PublicationMismatchException(\"MTU differs from live publication\", e);\n    }\n    throw e;\n}","preventionTips":["Use one canonical URI per stream across all code paths","Parse and diff ChannelUri params against the live publication before addPublication","Avoid embedding mtu-length unless you control every publisher to the stream"],"tags":["aeron","publication-reuse","mtu-length","channel-uri","state-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"}