aeron-io/aeron · error · IllegalArgumentException

invalid position

Error message

invalid position: <position>

What it means

ChannelUri.initialPosition validates that the requested position is non-negative and FRAME_ALIGNMENT-aligned (multiple of 32 bytes) before encoding it into the channel URI as initialPosition. Positions are term-based (termId/termOffset), so an unaligned or negative value would corrupt log buffer arithmetic.

Solutions

  1. Round the position down to a FRAME_ALIGNMENT multiple before passing it: position & ~(FRAME_ALIGNMENT - 1).
  2. Derive the position via LogBufferDescriptor.computePosition(termId, termOffset, positionBitsToShift(termLength), initialTermId) so alignment holds.
  3. Check for negative/overflow in the position computation (e.g. bad termId from a corrupted source).

Example fix

// before
uri.initialPosition(rawOffset, initialTermId, termLength);
// after
long aligned = rawOffset & ~(FrameDescriptor.FRAME_ALIGNMENT - 1);
uri.initialPosition(aligned, initialTermId, termLength);
Defensive patterns

Strategy: validation

Validate before calling

long aligned = position & ~(FrameDescriptor.FRAME_ALIGNMENT - 1);
if (position < 0 || aligned != position) throw new IllegalArgumentException("position must be frame-aligned");

Try / catch

try {
    uri.initialPosition(position, initialTermId, termLength);
} catch (IllegalArgumentException e) {
    // fall back to default (start at position 0) or align and retry
}

Prevention

When it happens

Trigger: Calling uri.initialPosition(position, initialTermId, termLength) with position < 0 or position not a multiple of FRAME_ALIGNMENT — e.g. a raw byte offset not rounded to frame alignment, or a computed position using wrong term length.

Common situations: Reconstructing a publication position from a recording/catalog value without alignment; computing position from termOffset that wasn't frame-aligned; off-by-one in position arithmetic after restart/failover.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at aeron-client/src/main/java/io/aeron/ChannelUri.java:353

            sb.setLength(sb.length() - 1);
        }

        return sb.toString();
    }

    /**
     * Initialise a channel for restarting a publication at a given position.
     *
     * @param position      at which the publication should be started.
     * @param initialTermId what which the stream would start.
     * @param termLength    for the stream.
     */
    public void initialPosition(final long position, final int initialTermId, final int termLength)
    {
        if (position < 0 || 0 != (position & (FRAME_ALIGNMENT - 1)))
        {
            throw new IllegalArgumentException("invalid position: " + position);
        }

        final int bitsToShift = LogBufferDescriptor.positionBitsToShift(termLength);
        final int termId = LogBufferDescriptor.computeTermIdFromPosition(position, bitsToShift, initialTermId);
        final int termOffset = (int)(position & (termLength - 1));

        put(INITIAL_TERM_ID_PARAM_NAME, Integer.toString(initialTermId));
        put(TERM_ID_PARAM_NAME, Integer.toString(termId));
        put(TERM_OFFSET_PARAM_NAME, Integer.toString(termOffset));
        put(TERM_LENGTH_PARAM_NAME, Integer.toString(termLength));
    }

    /**
     * Parse a {@link CharSequence} which contains an Aeron URI.
     *
     * @param uri to be parsed.
     * @return a new {@link ChannelUri} representing the URI string.
     */

View on GitHub (pinned to 6d60124e15)