apache/cassandra · warning · 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 invalid CRC. The end of segment marker should be zero.
What it means
During commit log replay, CommitLogSegmentReader.readSyncMarker validates each sync marker. When the marker CRC matches but the recorded 'end' is the segment end marker (0) while trailing bytes/CRC are nonzero, the header is deemed invalid and SegmentReadException(tolerable=true) is thrown: 'The end of segment marker should be zero.' It indicates a truncated or corrupted segment tail.
Source
Thrown at src/java/org/apache/cassandra/db/commitlog/CommitLogSegmentReader.java:203
// The next marker position and CRC value are not written atomically, so it is possible for the latter to
// still be zero after the former has been finalized, even though the mutations that follow it are valid.
// When there is no compression or encryption enabled, we can ignore a sync marker CRC mismatch and defer
// to the per-mutation CRCs, which may be preferable to preventing startup altogether.
if (allowSkipSyncMarkerCrc
&& descriptor.compression == null && !descriptor.getEncryptionContext().isEnabled()
&& filecrc == 0 && end != 0)
{
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);View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Let Cassandra skip the corrupt tail: replay handles SegmentReadException with tolerable=true by stopping at the last valid marker.
- Remove the affected segment from commitlog/ if replay is blocked and data loss is acceptable (it will be restored from SSTables).
- Restore from backup/SSTables and run a repair (nodetool repair) to re-sync replicas.
- Check disk health (dmesg, SMART) if corruption recurs.
Defensive patterns
Strategy: try-catch
Try / catch
try {
end = CommitLogSegmentReader.readSyncMarker(reader, offset);
} catch (SegmentReadException e) {
if (e.tolerable)
logger.warn("Corrupt segment tail, stopping replay at last valid marker: {}", e.getMessage());
else
throw e;
} Prevention
- Stop Cassandra cleanly; avoid copying live commit log segments for backups
- Monitor disk health and free space to prevent torn writes
- Keep the commitlog directory on reliable storage
When it happens
Trigger: Replaying a commit log whose final sync marker region contains a nonzero end marker or nonzero CRC where zeros are required — typically due to a crash mid-write, torn page, or manual file truncation at a non-marker boundary.
Common situations: Node crash without clean shutdown; disk full during segment close; file copied/synced mid-write (e.g. backup of live segment); corrupted storage.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 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/b320c43b44eb2595.
Report an issue: GitHub.