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
- Ensure termId - initialTermId is in [0, 2^31 - 1] by recomputing termId
- Reset initialTermId to 0 and adjust termId accordingly
- 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
- Compute termId = initialTermId + (int)(position / termLength) with 64-bit math
- Recompute position params when migrating streams between publications
- Document term-id wraparound behavior in config tooling
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
- invalid prefix
- params must be used as a complete set: initial-term-id…
- stream-id= does not match provided streamId=
- term-offset= must be a multiple of FRAME_ALIGNMENT: channel=
- term-offset= out of range: channel=
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)