apache/cassandra · error · SegmentReadException
Encountered bad header at position %d of commit log %s, with
Error message
Encountered bad header at position %d of commit log %s, with bad position but valid CRC
What it means
readSyncMarker also validates the marker's next-segment offset: end must lie within [offset, reader.length()]. When CRC is valid but the target position is out of range, SegmentReadException(tolerable=false) is thrown ('bad position but valid CRC'). A valid checksum pointing outside the file means the segment is truncated or from a different configuration — replay cannot continue safely.
Source
Thrown at src/java/org/apache/cassandra/db/commitlog/CommitLogSegmentReader.java:210
{
logger.warn("Skipping sync marker CRC check at position {} (end={}, calculated crc={}) of commit log {}." +
"Using per-mutation CRC checks to ensure correctness...",
offset, end, crc.getValue(), reader.getPath());
return end;
}
if (end != 0 || filecrc != 0)
{
String msg = String.format("Encountered bad header at position %d of commit log %s, with invalid CRC. " +
"The end of segment marker should be zero.", offset, reader.getPath());
throw new SegmentReadException(msg, true);
}
return -1;
}
else if (end < offset || end > reader.length())
{
String msg = String.format("Encountered bad header at position %d of commit log %s, with bad position but valid CRC", offset, reader.getPath());
throw new SegmentReadException(msg, false);
}
return end;
}
public static class SegmentReadException extends IOException
{
public final boolean invalidCrc;
public SegmentReadException(String msg, boolean invalidCrc)
{
super(msg);
this.invalidCrc = invalidCrc;
}
}
public static class SyncSegment
{
/** the 'buffer' to replay commit log data from */View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Restore the complete, untruncated commit log files from backup.
- Match commitlog_segment_size_in_mb to the value used when the logs were written.
- Accept partial replay: remove/discard the truncated segment; run nodetool repair so replicas restore lost data.
- If only this node is affected, wipe commitlog/ and bootstrap/repair from peers.
Defensive patterns
Strategy: validation
Validate before calling
if (markerEnd > reader.length() || markerEnd < offset)
throw new IOException("Segment truncated: marker end " + markerEnd + " outside file length " + reader.length()); Try / catch
try {
replaySegment(file);
} catch (SegmentReadException e) {
if (!e.tolerable) {
logger.error("Truncated commit log {}: restore full file or accept loss and repair", file);
// decide: abort vs. discard segment + nodetool repair
}
} Prevention
- Back up the entire commitlog directory atomically (verify file sizes after restore)
- Keep commitlog_segment_size_in_mb unchanged across restore/replay
- Run nodetool repair after discarding any damaged segment
When it happens
Trigger: Replaying a commit log shorter than the recorded marker end (truncation, incomplete copy, restored partial file), or a segment written with a different segment size than the current configuration.
Common situations: Restoring only part of the commitlog directory from backup; rsync/scp interrupted mid-copy; mismatched cassandra.yaml commitlog_segment_size_in_mb between writer and replayer; deliberately trimmed files.
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
- Encountered bad header at position %d of commit log %s, with
- Cannot safely construct descriptor for segment, either from
- Cannot safely construct descriptor for segment, as name desc
- Unknown commitlog version
- Invalid pair: '%s'
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/ecf016efede5b3c2.
Report an issue: GitHub.