apache/cassandra · error · IllegalStateException
commit log header has not been written
Error message
commit log header has not been written
What it means
CommitLogSegment.sync(flush) is an internal invariant: a segment must have had its CDC/commit log header written before any sync (including the close() path) can run. Throwing IllegalStateException("commit log header has not been written") signals that sync was invoked on a segment whose header allocation never completed — a bug in segment lifecycle rather than user input.
Source
Thrown at src/java/org/apache/cassandra/db/commitlog/CommitLogSegment.java:308
/**
* Wait for any appends or discardUnusedTail() operations started before this method was called
*/
void waitForModifications()
{
// issue a barrier and wait for it
appendOrder.awaitNewBarrier();
}
/**
* Update the chained markers in the commit log buffer and possibly force a disk flush for this segment file.
*
* @param flush true if the segment should flush to disk; else, false for just updating the chained markers.
*/
synchronized void sync(boolean flush)
{
if (!headerWritten)
throw new IllegalStateException("commit log header has not been written");
assert lastMarkerOffset >= lastSyncedOffset : String.format("commit log segment positions are incorrect: last marked = %d, last synced = %d",
lastMarkerOffset, lastSyncedOffset);
// check we have more work to do
final boolean needToMarkData = allocatePosition.get() > lastMarkerOffset + SYNC_MARKER_SIZE;
final boolean hasDataToFlush = lastSyncedOffset != lastMarkerOffset;
if (!(needToMarkData || hasDataToFlush))
return;
// Note: Even if the very first allocation of this sync section failed, we still want to enter this
// to ensure the segment is closed. As allocatePosition is set to 1 beyond the capacity of the buffer,
// this will always be entered when a mutation allocation has been attempted after the marker allocation
// succeeded in the previous sync.
assert buffer != null; // Only close once.
boolean close = false;
int startMarker = lastMarkerOffset;
int nextMarker, sectionEnd;
if (needToMarkData)
{View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Ensure the segment's header is written (allocatePosition / writeLogHeader path completes) before calling sync or close.
- Discard unused segments via the segment manager's discard path instead of closing them directly.
- Upgrade Cassandra: lifecycle bugs around header writing have been fixed in later releases.
- If seen in production without custom code, capture the stack and file a JIRA — it indicates an internal race.
Example fix
// before (test code) segment.sync(true); // after segment.writeLogHeader(commitLog.configuration().getCRCIgnoreChance()); segment.sync(true);
Defensive patterns
Strategy: try-catch
Validate before calling
if (!segment.isHeaderWritten())
throw new IllegalStateException("Sync attempted before header write"); Try / catch
try {
segment.sync(true);
} catch (IllegalStateException e) {
logger.error("Commit log segment lifecycle bug: {}", e.getMessage());
} Prevention
- Never call sync/close directly on raw CommitLogSegment instances in tests or tools
- Use the segment manager's allocate/discard APIs for lifecycle
- Keep Cassandra upgraded — header-write races are fixed over time
When it happens
Trigger: Calling sync() or close() on a CommitLogSegment before writeLogHeader has run (headerWritten == false), e.g. creating/discarding a segment abnormally during startup, tests manipulating segments directly, or a failure between segment creation and header write.
Common situations: Custom tooling or tests constructing CommitLogSegment instances and syncing/closing them directly; crashes during commit log segment initialization; bugs in custom CommitLogSegmentManager extensions.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- commit log sync marker's current file position %d is greater
- SASL negotiation not complete
- MBeanServer already initialized
- ScheduledThreadPoolExecutor has shut down.
- Missing required directive CommitLogSync
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/fea1375a2135a8a6.
Report an issue: GitHub.