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

  1. Remove term-id from the URI — it is dynamic state, not a stable config parameter.
  2. Match the current term-id reported in the error message.
  3. Close the existing publication first if you truly need a fresh term-id.
  4. 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

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


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)