aeron-io/aeron · error · InvalidMessage
Terminated prematurely
Error message
Terminated prematurely
What it means
DecodingState.incrementOffset advances the CBOR decode cursor and checks it against the buffer limit. If the increment would move the offset past the limit, the buffer is exhausted mid-message and InvalidMessage('Terminated prematurely') is thrown — the CBOR payload ended before the decoder expected it to.
Solutions
- Verify the buffer slice passed to the decoder covers the full record (use the encoded header's captureLength/length fields).
- Check that the event log wasn't truncated by the capture-length cap when writing.
- Add a remaining-bytes check before parsing variable-length fields.
- Re-capture with a larger capture length if records are being cut off.
Example fix
// before
decoder.decode(buffer, offset, buffer.capacity()); // limit beyond actual data
// after
final int limit = offset + CommonEventEncoder.encodedLength(captureLength);
if (limit > buffer.capacity()) throw new IllegalArgumentException("buffer too small");
decoder.decode(buffer, offset, limit); Defensive patterns
Strategy: validation
Validate before calling
if (limit - offset < minimumExpectedRecordLength)
{
throw new IllegalArgumentException("buffer slice too small for record");
} Try / catch
try
{
cborDecoder.decode(buffer, offset, limit);
}
catch (final InvalidMessage ex)
{
LOGGER.warn("truncated CBOR record at " + offset + ": " + ex.getMessage());
} Prevention
- Slice buffers using the header's encoded length, not capacity.
- Increase MAX_CAPTURE_LENGTH config if records are routinely truncated.
- Check remaining() before variable-length field reads.
- Handle InvalidMessage per record rather than failing the whole log.
When it happens
Trigger: Any parse step (parseMessage, parseString, parseLong, parseBoolean, parseEntry, parseNumber) consuming more bytes than remain — e.g. a declared string/byte-array length larger than the actual remaining buffer, or a truncated capture buffer.
Common situations: Truncated event-log fragments passed to the decoder; a log header claiming more bytes than the buffer holds; off-by-one in slicing the buffer around the log record.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/ba50b1b7ba152622.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-client/src/main/java/io/aeron/logging/DecodingState.java:51
{
this.buffer = buffer;
this.offset = initialOffset;
this.length = length;
this.limit = offset + length;
this.terminated = false;
}
void reset()
{
wrap(null, 0, 0);
}
void incrementOffset(final int increment)
{
this.offset += increment;
if (this.limit < this.offset)
{
throw new InvalidMessage("Terminated prematurely");
}
}
int remaining()
{
return this.limit - this.offset;
}
void ensureRemaining(final int count)
{
if (this.remaining() < count)
{
throw new InvalidMessage("Terminated prematurely");
}
}
int offset()
{View on GitHub (pinned to 6d60124e15)