aeron-io/aeron · error · IllegalStateException
formatMatchError(INITIAL_TERM_ID_PARAM_NAME…
Error message
formatMatchError(INITIAL_TERM_ID_PARAM_NAME, existingInitialTermId, params.initialTermId, existingChannel, channelUri)
What it means
term-id branch of confirmMatch: when the URI explicitly sets term-id and it differs from the existing publication's current term id, PublicationParams.confirmMatch throws IllegalStateException. Term id tracks the active term buffer position and must match on publication reuse.
Solutions
- Remove term-id from the URI — it is dynamic state, not a stable config parameter.
- Match the current term-id reported in the error message.
- Close the existing publication first if you truly need a fresh term-id.
- Whitelist which URI params you serialize (endpoint, stream-id, static params only).
Example fix
// before "aeron:udp?endpoint=localhost:40456|term-id=7" // existing is now at 9 // after "aeron:udp?endpoint=localhost:40456" // let driver manage term-id
Defensive patterns
Strategy: validation
Validate before calling
String tid = ChannelUri.parse(channel).get("term-id");
if (tid != null) {
throw new IllegalArgumentException("term-id is dynamic state; remove it from channel URI: " + channel);
} Try / catch
try {
pub = aeron.addPublication(channel, streamId);
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("existing publication has different 'term-id'")) {
channel = stripParam(channel, "term-id");
pub = aeron.addPublication(channel, streamId);
} else throw e;
} Prevention
- Never persist term-id in URIs; it changes as the publication advances
- Whitelist static params when serializing channels
- Strip term-id/term-offset when copying URIs from driver tooling
When it happens
Trigger: addPublication with URI term-id=X against an existing publication currently at term-id=Y; common when replaying or re-attaching with captured URIs that embedded a stale term-id.
Common situations: Persisted channel URIs that recorded term-id at snapshot time, later reused after the publication advanced; automation tooling that serializes all params including term-id.
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(SESSION_ID_PARAM_NAME, existingSessionId…
- formatMatchError(TERM_ID_PARAM_NAME, existingTermId…
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/c903062bea39f4e5.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-driver/src/main/java/io/aeron/driver/PublicationParams.java:341
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)
{
throw new IllegalStateException(formatMatchError(
TERM_OFFSET_PARAM_NAME,
String.valueOf(existingTermOffset),
String.valueOf(params.termOffset),
existingChannel,
channelUri.toString()));
}
}
View on GitHub (pinned to 6d60124e15)