aeron-io/aeron · error · IllegalStateException

existing publication has different 'mtu-length': existing=

Error message

existing publication has different 'mtu-length': existing={existingValue} requested={newValue} existingChannel={existingChannelUri} channel={newChannelUri}

What it means

When reusing an existing publication's log buffer (same stream on the same channel), the driver checks that any parameter explicitly present in the new channel URI matches the existing publication. PublicationParams.confirmMatch throws IllegalStateException when the URI specifies mtu-length but the existing log's MTU differs — Aeron will not silently re-configure a live publication.

Solutions

  1. Make the new channel URI identical to the existing one (same mtu-length) so publication reuse succeeds.
  2. Remove mtu-length from the URI entirely; note the check only fires when the URI explicitly contains mtu-length.
  3. Close the existing publication before adding one with the new MTU.
  4. Canonicalize URIs in application code (parse with ChannelUri and compare params) before addPublication.

Example fix

// before: conflicting MTU on reuse
aeron.addPublication("aeron:udp?endpoint=localhost:40456|mtu-length=8k", 1001); // existing runs 16k

// after
aeron.addPublication("aeron:udp?endpoint=localhost:40456|mtu-length=16k", 1001);
Defensive patterns

Strategy: try-catch

Validate before calling

ChannelUri uri = ChannelUri.parse(newChannel);
String requestedMtu = uri.get("mtu-length");
// only compare when explicitly present; otherwise reuse succeeds
if (requestedMtu != null && existingMtu != Integer.parseInt(requestedMtu)) {
    newChannel = setParam(newChannel, "mtu-length", String.valueOf(existingMtu));
}

Try / catch

try {
    pub = aeron.addPublication(channel, streamId);
} catch (IllegalStateException e) {
    if (e.getMessage().startsWith("existing publication has different 'mtu-length'")) {
        throw new PublicationMismatchException("MTU differs from live publication", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: A second addPublication call on a channel URI containing mtu-length while an existing publication for the same channel/session already runs with a different MTU (existing log buffer mtuLength != params.mtuLength).

Common situations: Two parts of an app adding the 'same' publication with slightly different URIs (one with mtu-length=8k, one without or with 16k); reconfiguring MTU after restart while old publication lingers; test harness vs prod URI drift.

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/9adf7f4c33a26b03. Report an issue: GitHub.

Appendix: source

Thrown at aeron-driver/src/main/java/io/aeron/driver/PublicationParams.java:301

        return "existing publication has different '" + paramName + "': existing=" +
            existingValue + " requested=" + newValue + " existingChannel=" + existingChannelUri +
            " channel=" + newChannelUri;
    }

    static void confirmMatch(
        final ChannelUri channelUri,
        final PublicationParams params,
        final RawLog rawLog,
        final int existingSessionId,
        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)

View on GitHub (pinned to 6d60124e15)