aeron-io/aeron · error · IllegalArgumentException

termOffset= out of range: channel=

Error message

termOffset=<termOffset> out of range: channel=<channelUri>

What it means

When an explicit join position is given via URI params, term-offset must be within [0, TERM_MAX_LENGTH] (the configured term buffer length limit). The driver validates the parsed value and rejects offsets outside that range with IllegalArgumentException.

Solutions

  1. Set term-offset within 0..TERM_MAX_LENGTH for the driver's term buffer length.
  2. Compute the offset from the desired position: termOffset = (int)(position & (termLength - 1)).
  3. Check the driver's term-buffer-length config and scale term-id accordingly instead of inflating the offset.

Example fix

// before
uri += "|term-offset=" + position; // absolute log position
// after
int termOffset = (int)(position & (termLength - 1));
uri += "|term-offset=" + termOffset;
Defensive patterns

Strategy: validation

Validate before calling

if (termOffset < 0 || termOffset > LogBufferDescriptor.TERM_MAX_LENGTH) {
    throw new IllegalArgumentException("termOffset out of range: " + termOffset);
}

Prevention

When it happens

Trigger: Subscription URI with term-offset negative or greater than LogBufferDescriptor.TERM_MAX_LENGTH (e.g. term-offset=99999999 with 64MB terms).

Common situations: Copy-pasting a file position instead of a term offset; assuming offsets are in bytes of the whole log rather than a single term; unit confusion (KB/MB).

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

Appendix: source

Thrown at aeron-driver/src/main/java/io/aeron/driver/SubscriptionParams.java:91

        count = termOffsetStr != null ? count + 1 : count;

        if (count > 0)
        {
            if (count < 3)
            {
                throw new IllegalArgumentException("params must be used as a complete set: " +
                    INITIAL_TERM_ID_PARAM_NAME + " " +
                    TERM_ID_PARAM_NAME + " " +
                    TERM_OFFSET_PARAM_NAME + " channel=" + channelUri);
            }

            params.initialTermId = Integer.parseInt(initialTermIdStr);
            params.termId = Integer.parseInt(termIdStr);
            params.termOffset = Integer.parseInt(termOffsetStr);

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

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

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

View on GitHub (pinned to 6d60124e15)