{"record":{"id":"aaf79962750643a3","repo":"aeron-io/aeron","slug":"existing-publication-has-different-term-length-existing","errorCode":null,"errorMessage":"existing publication has different 'term-length': existing={existingValue} requested={newValue} existingChannel={existingChannelUri} channel={newChannelUri}","messagePattern":"existing publication has different 'term-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":311,"sourceCode":"        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)\n        {\n            throw new IllegalStateException(formatMatchError(\n                SESSION_ID_PARAM_NAME,\n                String.valueOf(existingSessionId),\n                String.valueOf(params.sessionId),\n                existingChannel,\n                channelUri.toString()));\n        }\n\n        if (channelUri.containsKey(INITIAL_TERM_ID_PARAM_NAME) && params.initialTermId != existingInitialTermId)","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-driver/src/main/java/io/aeron/driver/PublicationParams.java#L293-L329","documentation":"confirmMatch equivalent for term-length: when the new channel URI explicitly carries term-length and the already-existing publication's log buffer was created with a different term length, PublicationParams.confirmMatch throws IllegalStateException. Aeron requires that re-additions of the same publication match the original buffer geometry exactly.","triggerScenarios":"addPublication on a URI with term-length=N where a live publication for the same channel/session exists with term-length=M (M != N), e.g. one subscriber-side template says 64k and the existing one was created with 1m.","commonSituations":"Reconnecting a publisher after config change while the driver still holds the old publication; multiple services publishing to the same endpoint with different term-length URIs; environment-specific URI configs drifting.","solutions":["Use the same term-length as the existing publication (read it from the error message: existing=...).","Omit term-length from the re-add URI (the mismatch check only applies when explicitly present).","Close/await closure of the existing publication, then add with the new term-length.","Share one canonical URI constant across all publishers to a given stream."],"exampleFix":"// before\naeron.addPublication(\"aeron:udp?endpoint=localhost:40456|term-length=64k\", 1001); // existing is 1m\n\n// after\naeron.addPublication(\"aeron:udp?endpoint=localhost:40456|term-length=1m\", 1001);","handlingStrategy":"try-catch","validationCode":"ChannelUri uri = ChannelUri.parse(newChannel);\nString requestedTermLen = uri.get(\"term-length\");\nif (requestedTermLen != null && existingTermLength != Integer.parseInt(requestedTermLen)) {\n    newChannel = setParam(newChannel, \"term-length\", String.valueOf(existingTermLength));\n}","typeGuard":null,"tryCatchPattern":"try {\n    pub = aeron.addPublication(channel, streamId);\n} catch (IllegalStateException e) {\n    if (e.getMessage().startsWith(\"existing publication has different 'term-length'\")) {\n        throw new PublicationMismatchException(\"Term length differs from live publication\", e);\n    }\n    throw e;\n}","preventionTips":["Source term-length from shared config, not per-service constants","Diff URIs against the existing publication's params before re-adding","On restart, reuse the previously persisted URI verbatim"],"tags":["aeron","publication-reuse","term-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"}