aeron-io/aeron · error · IllegalStateException
existing publication has different 'term-length': existing=
Error message
existing publication has different 'term-length': existing={existingValue} requested={newValue} existingChannel={existingChannelUri} channel={newChannelUri} What it means
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.
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.
Example fix
// before
aeron.addPublication("aeron:udp?endpoint=localhost:40456|term-length=64k", 1001); // existing is 1m
// after
aeron.addPublication("aeron:udp?endpoint=localhost:40456|term-length=1m", 1001); Defensive patterns
Strategy: try-catch
Validate before calling
ChannelUri uri = ChannelUri.parse(newChannel);
String requestedTermLen = uri.get("term-length");
if (requestedTermLen != null && existingTermLength != Integer.parseInt(requestedTermLen)) {
newChannel = setParam(newChannel, "term-length", String.valueOf(existingTermLength));
} Try / catch
try {
pub = aeron.addPublication(channel, streamId);
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("existing publication has different 'term-length'")) {
throw new PublicationMismatchException("Term length differs from live publication", e);
}
throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- existing publication has different 'mtu-length': existing=
- formatMatchError(paramName, existingValue, paramsValue…
- formatMatchError(SESSION_ID_PARAM_NAME, existingSessionId…
- formatMatchError(INITIAL_TERM_ID_PARAM_NAME…
- formatMatchError(TERM_ID_PARAM_NAME, existingTermId…
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/aaf79962750643a3.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-driver/src/main/java/io/aeron/driver/PublicationParams.java:311
final String existingChannel,
final int existingInitialTermId,
final int existingTermId,
final int existingTermOffset)
{
final int mtuLength = LogBufferDescriptor.mtuLength(rawLog.metaData());
if (channelUri.containsKey(MTU_LENGTH_PARAM_NAME) && mtuLength != params.mtuLength)
{
throw new IllegalStateException(formatMatchError(
MTU_LENGTH_PARAM_NAME,
String.valueOf(mtuLength),
String.valueOf(params.mtuLength),
existingChannel,
channelUri.toString()));
}
if (channelUri.containsKey(TERM_LENGTH_PARAM_NAME) && rawLog.termLength() != params.termLength)
{
throw new IllegalStateException(formatMatchError(
TERM_LENGTH_PARAM_NAME,
String.valueOf(rawLog.termLength()),
String.valueOf(params.termLength),
existingChannel,
channelUri.toString()));
}
if (channelUri.containsKey(SESSION_ID_PARAM_NAME) && params.sessionId != existingSessionId)
{
throw new IllegalStateException(formatMatchError(
SESSION_ID_PARAM_NAME,
String.valueOf(existingSessionId),
String.valueOf(params.sessionId),
existingChannel,
channelUri.toString()));
}
if (channelUri.containsKey(INITIAL_TERM_ID_PARAM_NAME) && params.initialTermId != existingInitialTermId)View on GitHub (pinned to 6d60124e15)