aeron-io/aeron · error · IllegalStateException
formatMatchError(SESSION_ID_PARAM_NAME, existingSessionId…
Error message
formatMatchError(SESSION_ID_PARAM_NAME, existingSessionId, params.sessionId, existingChannel, channelUri)
What it means
initial-term-id branch of confirmMatch: when the channel URI explicitly includes initial-term-id and the requested value differs from the existing publication's initial term id stored in its log buffer metadata, PublicationParams.confirmMatch throws IllegalStateException. Initial term id pins where the term counter starts and cannot change on reuse.
Solutions
- Use the same initial-term-id as the existing publication (see existing= in the message).
- Remove initial-term-id from the URI so the existing buffer's value is accepted.
- Ensure the prior publication is fully closed before adding with a new initial-term-id.
- Persist the chosen initial-term-id (e.g. in a ledger) so restarts reuse it rather than generating a fresh value.
Example fix
// before "aeron:udp?endpoint=localhost:40456|initial-term-id=-42" // existing buffer has 0 // after "aeron:udp?endpoint=localhost:40456|initial-term-id=0"
Defensive patterns
Strategy: try-catch
Validate before calling
String iti = ChannelUri.parse(channel).get("initial-term-id");
if (iti != null && existingInitialTermId != Long.decode(iti)) {
throw new IllegalArgumentException("initial-term-id " + iti + " conflicts with existing publication " + existingInitialTermId);
} Try / catch
try {
pub = aeron.addPublication(channel, streamId);
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("existing publication has different 'initial-term-id'")) {
throw new PublicationMismatchException("Initial term id differs", e);
}
throw e;
} Prevention
- Persist initial-term-id across restarts if determinism is required
- Omit initial-term-id unless replay/deterministic setup demands it
- Derive it from the same seed/config on all instances sharing a stream
When it happens
Trigger: Re-adding a publication with URI initial-term-id=X while the existing log buffer was built with initial-term-id=Y; typically happens with deterministic/replayable publisher setups that hardcode initial-term-id differently across processes.
Common situations: Recording/replay systems that set initial-term-id per run; crash-restart code generating a new initial-term-id while the old publication is still registered; two app instances using the same deterministic channel config but different seeds.
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=
- existing publication has different 'term-length': existing=
- formatMatchError(paramName, existingValue, paramsValue…
- 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/8b548f53082389e3.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-driver/src/main/java/io/aeron/driver/PublicationParams.java:331
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)
{
throw new IllegalStateException(formatMatchError(
INITIAL_TERM_ID_PARAM_NAME,
String.valueOf(existingInitialTermId),
String.valueOf(params.initialTermId),
existingChannel,
channelUri.toString()));
}
if (channelUri.containsKey(TERM_ID_PARAM_NAME) && params.termId != existingTermId)
{
throw new IllegalStateException(formatMatchError(
TERM_ID_PARAM_NAME,
String.valueOf(existingTermId),
String.valueOf(params.termId),
existingChannel,
channelUri.toString()));
}
if (channelUri.containsKey(TERM_OFFSET_PARAM_NAME) && params.termOffset != existingTermOffset)View on GitHub (pinned to 6d60124e15)