aeron-io/aeron · error · InvalidChannelException

MTU greater than max message length for term length: mtu=

Error message

MTU greater than max message length for term length: mtu={mtuLength} maxMessageLength={maxMessageLength} termLength={termLength} channel={channelUri}

What it means

Aeron rejects a publication/subscription channel whose mtu-length exceeds the maximum message length derivable from the term buffer length (FrameDescriptor.computeMaxMessageLength, termLength minus framing header space). The driver throws InvalidChannelException in PublicationParams.getMtuLength because fragments larger than what a term buffer can frame could never be delivered. MTU must be <= maxMessageLength and is also typically a multiple of FrameDescriptor.FRAGMENT_ALIGNMENT (32).

Solutions

  1. Lower the mtu-length URI parameter so it is <= computeMaxMessageLength(term-length) (termLength - 32, aligned to 32 bytes).
  2. Increase term-length to at least mtu + framing overhead (e.g. mtu-length=16384 requires term-length of at least 64K in practice).
  3. Remove the explicit mtu-length parameter and let the driver default (ctx.publicationTermWindowLength / defaultMtuLength) apply.
  4. If the values come from code, validate with AeronThread-safe checks before addPublication: FrameDescriptor.computeMaxMessageLength(termLength) >= mtuLength.

Example fix

// before
Aeron.connect().addPublication("aeron:udp?endpoint=224.0.1.1:40456|term-length=64k|mtu-length=128k", 1);

// after (mtu fits within term length)
Aeron.connect().addPublication("aeron:udp?endpoint=224.0.1.1:40456|term-length=64k|mtu-length=16k", 1);
Defensive patterns

Strategy: validation

Validate before calling

import static io.aeron.logbuffer.FrameDescriptor.computeMaxMessageLength;

void checkMtu(int mtuLength, int termLength) {
    int max = computeMaxMessageLength(termLength);
    if (mtuLength > max) {
        throw new IllegalArgumentException("mtu-length=" + mtuLength + " exceeds maxMessageLength=" + max + " for term-length=" + termLength);
    }
}

Try / catch

try {
    publication = aeron.addPublication(channel, streamId);
} catch (InvalidChannelException e) {
    log.error("Rejecting channel config: {}", e.getMessage());
    throw new ConfigException(channel, e);
}

Prevention

When it happens

Trigger: Adding a publication or exclusive publication where the channel URI sets mtu-length (or the context default) larger than computeMaxMessageLength(term-length), e.g. mtu-length=16384 with term-length=16384, or a huge mtu-length like 1Mb with the default 64Kb term length.

Common situations: Copy-pasting an mtu-length from another transport config; setting term-length and mtu-length to the same value forgetting header overhead; tuning for throughput by raising MTU without raising term-length; Aeron-specific gotcha since MTU also must fit UDP datagram limits.

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

Appendix: source

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

            this.termLength = termLength;
        }
    }

    private void getMtuLength(final ChannelUri channelUri)
    {
        final String mtuParam = channelUri.get(MTU_LENGTH_PARAM_NAME);
        if (null != mtuParam)
        {
            final int mtuLength = (int)SystemUtil.parseSize(MTU_LENGTH_PARAM_NAME, mtuParam);
            Configuration.validateMtuLength(mtuLength);
            validateMtuLength(this, mtuLength, channelUri);
            this.mtuLength = mtuLength;
        }

        final int maxMessageLength = FrameDescriptor.computeMaxMessageLength(termLength);
        if (mtuLength > maxMessageLength)
        {
            throw new InvalidChannelException("MTU greater than max message length for term length: mtu=" +
                mtuLength + " maxMessageLength=" + maxMessageLength + " termLength=" + termLength + " channel=" +
                channelUri);
        }
    }

    static void validateTermLength(
        final PublicationParams params, final int explicitTermLength, final ChannelUri channelUri)
    {
        if (params.isSessionIdTagged && explicitTermLength != params.termLength)
        {
            throw new InvalidChannelException(
                TERM_LENGTH_PARAM_NAME + "=" + explicitTermLength + " does not match session-id tag value: channel=" +
                channelUri);
        }
    }

    static void validateMtuLength(
        final PublicationParams params, final int explicitMtuLength, final ChannelUri channelUri)

View on GitHub (pinned to 6d60124e15)