apache/cassandra · error · IOException
Seeking to a partition at: ${position} did not land after an
Error message
Seeking to a partition at: ${position} did not land after an end-of-partition marker; found 0x${marker} What it means
When seeking to a partition start, SSTableCursorReader reads the byte immediately before the target position and requires the exact END_OF_PARTITION marker byte (a stricter test than isEndOfPartition's bit check). Any other byte means the seek position is not a true partition boundary, indicating corrupt bounds or a corrupt data file.
Source
Thrown at src/java/org/apache/cassandra/io/sstable/SSTableCursorReader.java:725
/**
* Seeks to the start of a partition. Every partition but the file's first follows an
* end-of-partition marker, and reading that byte leaves the reader at the partition start.
*/
private void seekPartition(long position) throws IOException
{
if (position == 0)
{
if (dataReader.getPosition() != 0)
dataReader.seek(0);
return;
}
dataReader.seek(position - 1);
// The exact byte, not isEndOfPartition, which is (b & 1) != 0 and so accepts 128 of the 256
// values. The writer emits END_OF_PARTITION alone for this marker, so the stronger test
// costs nothing and rejects a mis-sized bound that happens to land on an odd byte.
int marker = dataReader.readUnsignedByte();
if (marker != UnfilteredSerializer.END_OF_PARTITION)
throw new IOException("Seeking to a partition at: " + position + " did not land after an end-of-partition marker; found 0x"
+ Integer.toHexString(marker));
}
// struct partition {
// struct partition_header header
// optional<struct row> row
// struct unfiltered unfiltereds[];
//};
public int readPartitionHeader(PartitionDescriptor header)
{
if (state != PARTITION_START) throw new IllegalStateException();
resetOnPartitionStart();
try
{
header.load(dataReader, deletionTimeSerializer);
return checkNextFlagsAfterPartitionStart(false);
}
catch (Exception e)View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Run nodetool verify / sstableverify on the sstable to confirm corruption.
- Run nodetool scrub (sstablescrub) to repair or quarantine the corrupt sstable.
- Restore the sstable from backup and run nodetool repair to re-replicate data.
- If offsets come from custom tooling, fix bound computation to land exactly one byte past the END_OF_PARTITION marker.
Example fix
// before
reader.seekToPartition(bounds.lowerPosition);
// after
try {
reader.seekToPartition(bounds.lowerPosition);
} catch (IOException e) {
throw new CorruptSSTableException(e, ssTableReader.getFilename()); // treat as corruption
} Defensive patterns
Strategy: try-catch
Try / catch
try {
cursor.seekToPartition(pos);
} catch (IOException e) {
if (e.getMessage().contains("end-of-partition marker"))
throw new CorruptSSTableException(e, filename); // route to scrub/verify
throw e;
} Prevention
- Run periodic nodetool verify to detect data-file corruption early.
- Generate partition bounds only from tools that validate end-of-partition markers.
- Verify digests after copying sstables between nodes.
- Avoid manually truncating Data.db.
When it happens
Trigger: Seeking to a partition start offset from bounds/index metadata that does not sit exactly one byte past an end-of-partition marker — mis-sized bounds landing one byte off, or Data.db corruption.
Common situations: Corrupted data files after disk failures; hand-edited or wrongly generated partition bounds; truncated Data.db shifting offsets; buggy tools computing partition start positions.
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
- Corrupt flags value for clustering prefix (isStatic flag set
- Corrupted sstable. Invalid flags found deserializing Deletio
- Failed to import sstable <filename>
- CorruptSSTableException wrapping IOException for ${path}
- CorruptSSTableException wrapping IOException cause for ${fil
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/80e50bca760dcfd5.
Report an issue: GitHub.