aeron-io/aeron · error · IllegalArgumentException
position not aligned to FRAME_ALIGNMENT
Error message
position not aligned to FRAME_ALIGNMENT
What it means
Image.validatePosition() also throws this IllegalArgumentException when the supplied position is not a multiple of FRAME_ALIGNMENT (32 bytes). Aeron fragment positions must land on frame boundaries because positions encode offsets into term buffers where frames are frame-aligned.
Solutions
- Round the position down to the nearest FRAME_ALIGNMENT (32) multiple: position & ~(FRAME_ALIGNMENT - 1).
- Only set positions obtained from Image.position() or fragment-consumed offsets, never hand-computed offsets.
- Fix the offset arithmetic so frame header length is included and each frame is counted at its aligned size.
Example fix
// before image.position(offset); // after image.position(offset & ~(FRAME_ALIGNMENT - 1)); // FRAME_ALIGNMENT = 32
Defensive patterns
Strategy: validation
Validate before calling
if ((position & (FRAME_ALIGNMENT - 1)) != 0) { // FRAME_ALIGNMENT = 32
position &= ~(FRAME_ALIGNMENT - 1); // align down
} Try / catch
try {
image.position(pos);
} catch (IllegalArgumentException e) {
image.position(pos & ~(FRAME_ALIGNMENT - 1));
} Prevention
- Track positions only as frame-aligned offsets returned by Aeron APIs.
- Include frame header length in offset arithmetic, and align each frame to 32 bytes.
- Assert alignment (position % 32 == 0) in debug builds when persisting positions.
When it happens
Trigger: Calling Image.position(long) or similar with a value not aligned to FRAME_ALIGNMENT, e.g. a raw byte offset computed from fragment payload sizes rather than the value returned by fragment resolution functions.
Common situations: Computing positions by adding payload length instead of the aligned frame length; persisting positions after custom buffer arithmetic; tracking positions in an external consumer that loses alignment.
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
- position out of range: -
- invalid position
- MTU not a multiple of FRAME_ALIGNMENT: mtu=
- term offset not multiple of FRAME_ALIGNMENT
- invalid position= does not have frame alignment=
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/30cc93487c7cab9c.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-client/src/main/java/io/aeron/Image.java:789
private UnsafeBuffer activeTermBuffer(final long position)
{
return termBuffers[LogBufferDescriptor.indexByPosition(position, positionBitsToShift)];
}
private void validatePosition(final long position)
{
final long currentPosition = subscriberPosition.get();
final long limitPosition = (currentPosition - (currentPosition & termLengthMask)) + termLengthMask + 1;
if (position < currentPosition || position > limitPosition)
{
throw new IllegalArgumentException(
position + " position out of range: " + currentPosition + "-" + limitPosition);
}
if (0 != (position & (FRAME_ALIGNMENT - 1)))
{
throw new IllegalArgumentException(position + " position not aligned to FRAME_ALIGNMENT");
}
}
LogBuffers logBuffers()
{
return logBuffers;
}
void close()
{
finalPosition = subscriberPosition.getVolatile();
eosPosition = LogBufferDescriptor.endOfStreamPosition(logBuffers.metaDataBuffer());
isEos = finalPosition >= eosPosition;
isRevoked = LogBufferDescriptor.isPublicationRevoked(logBuffers.metaDataBuffer());
isClosed = true;
}
/**View on GitHub (pinned to 6d60124e15)