aeron-io/aeron · critical · IllegalStateException
Message length < 0, file corrupt?
Error message
Message length < 0, file corrupt?
What it means
While scanning message records in the node state file, scanForMessageTypeOffset read a messageLength that is negative. Since message lengths are unsigned 32-bit SBE block lengths, a negative value means the file's framing is corrupted or the read pointer is misaligned. The library throws IllegalStateException rather than proceeding with a bogus length.
Solutions
- Treat the node state file as corrupt and restore it from a clean backup of the cluster data directory.
- Rejoin the cluster / rebuild local state by re-fetching from the leader instead of replaying the damaged file.
- Check for concurrent writers — ensure only one process opens the node state file.
- Verify disk health and free space; confirm writes are properly flushed by the Aeron version in use.
Example fix
// before
final long offset = nodeStateFile.candidateTermOffset(); // throws if length < 0
// after
try { final long offset = nodeStateFile.candidateTermOffset(); } catch (IllegalStateException e) { restoreStateFileFromBackup(); } Defensive patterns
Strategy: try-catch
Validate before calling
final long fileSize = file.length(); if (fileSize < MessageHeaderEncoder.ENCODED_LENGTH * 2) { treatAsCorrupt(file); } Try / catch
try { final long offset = nodeStateFile.candidateTermOffset(); } catch (IllegalStateException e) { markStateFileCorrupt(file); rebuildStateFromLeader(); } Prevention
- Ensure only one process opens the node state file at a time.
- Monitor disk space/health on cluster members.
- Restore from backup rather than attempting to repair torn records manually.
When it happens
Trigger: Iterating messages via footerOffset() or candidateTermOffset() over a NodeStateFile whose bytes were truncated mid-record, overwritten, or written with a mismatched format; reading a file from disk while another process is still writing it.
Common situations: Disk full during a state write leaving a torn record; unclean shutdown without fsync; manual editing/copying of cluster data files; concurrent access to the state file from two processes.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- failed to find CandidateTerm entry
- not found in
- ${eventCode}: ${detail}
- clusterMembers and endpoints differ
- response publication already added
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/bed3cdc3f7dcc702.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-cluster/src/main/java/io/aeron/cluster/NodeStateFile.java:335
while (position < buffer.capacity())
{
messageHeaderDecoder.wrap(buffer, position);
final int messageLength = messageHeaderDecoder.frameLength();
if (templateId == messageHeaderDecoder.templateId())
{
return position;
}
else if (NodeStateFooterEncoder.TEMPLATE_ID == messageHeaderDecoder.templateId())
{
return Aeron.NULL_VALUE;
}
if (messageLength < 0)
{
throw new IllegalStateException("Message length < 0, file corrupt?");
}
else if (0 == messageLength)
{
return Aeron.NULL_VALUE;
}
position += align(messageLength, ALIGNMENT);
}
return Aeron.NULL_VALUE;
}
/**
* Wrapper class for the candidate term.
*/
public final class CandidateTerm
{
private CandidateTerm()View on GitHub (pinned to 6d60124e15)