aeron-io/aeron · error · IllegalStateException

existing publication has different spiesSimulateConnection…

Error message

existing publication has different spiesSimulateConnection: existing=<existing> requested=<requested> existingChannel=<existingChannel> channel=<channel>

What it means

Aeron throws this IllegalStateException when adding a publication on a channel that already has a publication (matched by channel/streamId) whose `spiesSimulateConnection` URI parameter differs from the newly requested value. Parameters of publications sharing the same network channel must be consistent, so the driver rejects the conflicting add instead of silently merging settings.

Solutions

  1. Align the spiesSimulateConnection value in the new addPublication call with the existing publication's value shown in the message
  2. Close the existing publication (or restart the client/driver) before adding one with different params
  3. Centralize channel URI construction so the param is defined in one place
  4. Verify both sides pass the same explicit value rather than relying on defaults

Example fix

// before
aeron.addPublication("aeron:udp?endpoint=224.0.1.1:40456|spiesSimulateConnection=false", 1001);
aeron.addExclusivePublication("aeron:udp?endpoint=224.0.1.1:40456|spiesSimulateConnection=true", 1001);
// after
aeron.addPublication("aeron:udp?endpoint=224.0.1.1:40456|spiesSimulateConnection=true", 1001);
aeron.addExclusivePublication("aeron:udp?endpoint=224.0.1.1:40456|spiesSimulateConnection=true", 1001);
Defensive patterns

Strategy: validation

Validate before calling

if (existingParams != null && existingParams.spiesSimulateConnection != requestedSpiesSimulateConnection) {
    throw new IllegalArgumentException("spiesSimulateConnection must match existing publication on " + channel);
}

Try / catch

try { publication = aeron.addPublication(uri, streamId); }
catch (IllegalStateException e) {
    if (e.getMessage().contains("spiesSimulateConnection")) {
        publication = aeron.addPublication(reuseExistingChannelParams(uri), streamId);
    } else throw e;
}

Prevention

When it happens

Trigger: Calling Aeron.addPublication/addExclusivePublication with a URI whose existing counterpart was added earlier with the opposite `spiesSimulateConnection=true|false` value on the same channel and stream.

Common situations: Mixing app code (spies enabled for testing tools like Aeron Archive replays) with config-driven code (spies disabled); changing the driver-level default between restarts while publications persist; a shared channel string constructed in two places with divergent params.

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/04b30e3268254c42. Report an issue: GitHub.

Appendix: source

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

        {
            throw new IllegalStateException(formatMatchError(
                TERM_OFFSET_PARAM_NAME,
                String.valueOf(existingTermOffset),
                String.valueOf(params.termOffset),
                existingChannel,
                channelUri.toString()));
        }
    }

    static void validateSpiesSimulateConnection(
        final PublicationParams params,
        final boolean existingSpiesSimulateConnection,
        final String channel,
        final String existingChannel)
    {
        if (params.spiesSimulateConnection != existingSpiesSimulateConnection)
        {
            throw new IllegalStateException("existing publication has different spiesSimulateConnection: existing=" +
                existingSpiesSimulateConnection + " requested=" + params.spiesSimulateConnection +
                " existingChannel=" + existingChannel + " channel=" + channel);
        }
    }

    static void validateMtuForSndbuf(
        final PublicationParams params,
        final int channelSocketSndbufLength,
        final MediaDriver.Context ctx,
        final String channel,
        final String existingChannel)
    {
        if (0 != channelSocketSndbufLength && params.mtuLength > channelSocketSndbufLength)
        {
            throw new IllegalStateException(
                "MTU greater than SO_SNDBUF for channel: mtu=" + params.mtuLength +
                " so-sndbuf=" + channelSocketSndbufLength +
                (null == existingChannel ? "" : (" existingChannel=" + existingChannel)) +

View on GitHub (pinned to 6d60124e15)