aeron-io/aeron · error · IllegalStateException

MTU greater than SO_SNDBUF for channel: mtu=

Error message

MTU greater than SO_SNDBUF for channel: mtu=<mtuLength> so-sndbuf=<channelSocketSndbufLength> existingChannel=<existingChannel> channel=<channel>

What it means

The channel URI sets an explicit socket-sndbuf (SO_SNDBUF) smaller than the publication MTU; Aeron throws IllegalStateException because each datagram must fit in the socket send buffer or sends would fail with EMSGSIZE. Thrown by validateMtuForSndbuf when validating publication params.

Solutions

  1. Raise the channel's so-sndbuf URI value to at least the mtu length
  2. Lower the mtu URI value to at most so-sndbuf
  3. Remove the explicit so-sndbuf so the OS default check applies instead
  4. Check the driver's osDefaultSocketSndbufLength via error 652 path if sndbuf is 0

Example fix

// before
"aeron:udp?endpoint=localhost:40456|mtu=16384|so-sndbuf=8192"
// after
"aeron:udp?endpoint=localhost:40456|mtu=16384|so-sndbuf=131072"
Defensive patterns

Strategy: validation

Validate before calling

long sndbuf = getUriParam(uri, "so-sndbuf", -1);
int mtu = getUriParam(uri, "mtu", 4096);
if (sndbuf > 0 && mtu > sndbuf) throw new IllegalArgumentException("mtu must be <= so-sndbuf");

Try / catch

try { publication = aeron.addPublication(uri, streamId); }
catch (IllegalStateException e) {
    if (e.getMessage().contains("MTU greater than SO_SNDBUF")) {
        throw new ConfigurationException("Channel " + uri + " has mtu exceeding so-sndbuf", e);
    } throw e;
}

Prevention

When it happens

Trigger: Adding a network publication whose URI has both `mtu=` (e.g. 16384) and `so-sndbuf=` smaller than the MTU, or a `session-id` tag referencing an existing publication with a larger MTU.

Common situations: Tuning for throughput by raising MTU while leaving a low so-sndbuf; copying channel strings between hosts with different buffer settings; session-id tagged publications inheriting a large MTU.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12). Data as JSON: /api/errors/e79c22e8a4862fc4. Report an issue: GitHub.

Appendix: source

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

    {
        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)) +
                " channel=" + channel);
        }
        else if (0 == channelSocketSndbufLength && params.mtuLength > ctx.osDefaultSocketSndbufLength())
        {
            throw new IllegalStateException(
                "MTU greater than SO_SNDBUF for channel: mtu=" + params.mtuLength +
                " so-sndbuf=" + ctx.osDefaultSocketSndbufLength() + " (OS default)" +
                (null == existingChannel ? "" : (" existingChannel=" + existingChannel)) +
                " channel=" + channel);
        }
    }

    private void getLingerTimeoutNs(final ChannelUri channelUri, final MediaDriver.Context ctx)
    {
        final String lingerParam = channelUri.get(LINGER_PARAM_NAME);

View on GitHub (pinned to 6d60124e15)