aeron-io/aeron · error · InvalidChannelException

difference greater than 2^31 - 1: initial-term-id=

Error message

difference greater than 2^31 - 1: initial-term-id={initialTermId} when term-id={termId} channel={channelUri}

What it means

The pair (initialTermId, termId) encodes how many terms the publication has advanced; termId - initialTermId must be non-negative when interpreted as a signed 32-bit difference. If the difference is negative the implied start position exceeds 2^31 - 1 terms, which Aeron rejects.

Solutions

  1. Ensure termId - initialTermId is in [0, 2^31 - 1] by recomputing termId
  2. Reset initialTermId to 0 and adjust termId accordingly
  3. Remove the position-pinning params and let the publication start fresh

Example fix

// before
"aeron:udp?endpoint=...:40456|initial-term-id=5|term-id=3|term-offset=0"
// after
"aeron:udp?endpoint=...:40456|initial-term-id=3|term-id=5|term-offset=0"
Defensive patterns

Strategy: validation

Validate before calling

if (((termId - initialTermId) & 0xFFFFFFFFL) >= (1L << 31)) throw new IllegalArgumentException("termId too far from initialTermId");

Try / catch

try { pub = aeron.addPublication(uri, streamId); } catch (InvalidChannelException e) { log.error("term id range invalid: {}", e.getMessage()); }

Prevention

When it happens

Trigger: A channel URI where termId is numerically less than initialTermId (e.g. initial-term-id=1|term-id=0), parsed in getPublicationParams.

Common situations: Computing termId = initialTermId + (position/termLength) with wraparound mishandled; using a raw session termId from an older stream as initialTermId; copying params between streams with different histories.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

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

                    TERM_LENGTH_PARAM_NAME + "=" + params.termLength + ": channel=" + channelUri);
            }

            if (params.termOffset < 0 || params.termOffset > LogBufferDescriptor.TERM_MAX_LENGTH)
            {
                throw new InvalidChannelException(
                    TERM_OFFSET_PARAM_NAME + "=" + params.termOffset + " out of range: channel=" + channelUri);
            }

            if (!FrameDescriptor.isFrameAligned(params.termOffset))
            {
                throw new InvalidChannelException(
                    TERM_OFFSET_PARAM_NAME + "=" + params.termOffset +
                    " must be a multiple of FRAME_ALIGNMENT: channel=" + channelUri);
            }

            if (params.termId - params.initialTermId < 0)
            {
                throw new InvalidChannelException(
                    "difference greater than 2^31 - 1: " + INITIAL_TERM_ID_PARAM_NAME + "=" +
                    params.initialTermId + " when " + TERM_ID_PARAM_NAME + "=" + params.termId + " channel=" +
                    channelUri);
            }

            params.hasPosition = true;
        }
        else
        {
            params.initialTermId = BitUtil.generateRandomisedId();
            params.termId = params.initialTermId;
            params.termOffset = 0;
        }

        params.isResponse = CONTROL_MODE_RESPONSE.equals(channelUri.get(MDC_CONTROL_MODE_PARAM_NAME));
        params.responseCorrelationId = parseResponseCorrelationId(channelUri);

        return params;

View on GitHub (pinned to 6d60124e15)