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
- Raise the channel's so-sndbuf URI value to at least the mtu length
- Lower the mtu URI value to at most so-sndbuf
- Remove the explicit so-sndbuf so the OS default check applies instead
- 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
- Derive so-sndbuf as max(mtu, defaultSndbuf) when generating URIs
- Keep mtu and so-sndbuf in the same config block so they are reviewed together
- Test channel configs with a startup validation pass before adding publications
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
- MTU greater than SO_SNDBUF for channel: mtu=
- could not resolve control address:
- could not resolve endpoint address:
- either 'endpoint' or 'control' must be specified for UDP.
- Invalid length
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)