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
- Round the position down to a FRAME_ALIGNMENT multiple before passing it: position & ~(FRAME_ALIGNMENT - 1).
- Derive the position via LogBufferDescriptor.computePosition(termId, termOffset, positionBitsToShift(termLength), initialTermId) so alignment holds.
- 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
- Compute positions via LogBufferDescriptor.computePosition(...) rather than manual arithmetic
- Align any raw offsets to FRAME_ALIGNMENT (32 bytes) before use
- Validate positions restored from recordings/catalogs before replaying
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
- invalid position= does not have frame alignment=
- MTU not a multiple of FRAME_ALIGNMENT: mtu=
- counter id is not allocated, state
- counter id is negative
- counter id out of range: 0 - maxCounterId=
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)