apache/cassandra · critical · CorruptSSTableException
CorruptSSTableException wrapping IOException for ${path}
Error message
CorruptSSTableException wrapping IOException for ${path} What it means
SSTableIdentityIterator.create() reads a partition's rows from an SSTable data file. If any IOException occurs while parsing the file, the sstable is marked suspect and the IOException is wrapped in a CorruptSSTableException carrying the file path. This is Cassandra's standard signal that the on-disk SSTable data could not be read or is structurally damaged.
Source
Thrown at src/java/org/apache/cassandra/io/sstable/SSTableIdentityIterator.java:82
{
return create(sstable, sstable.metadata(), file, key);
}
public static SSTableIdentityIterator create(SSTableReader sstable, TableMetadata tableMetadata, RandomAccessReader file, DecoratedKey key)
{
try
{
DeletionTime partitionLevelDeletion = DeletionTime.getSerializer(sstable.descriptor.version).deserialize(file);
if (!partitionLevelDeletion.validate())
UnfilteredValidation.handleInvalid(tableMetadata, key, sstable, "partitionLevelDeletion="+partitionLevelDeletion.toString());
DeserializationHelper helper = new DeserializationHelper(tableMetadata, sstable.descriptor.version.correspondingMessagingVersion(), DeserializationHelper.Flag.LOCAL);
SSTableSimpleIterator iterator = SSTableSimpleIterator.create(tableMetadata, file, sstable.header, helper, partitionLevelDeletion);
return new SSTableIdentityIterator(sstable, key, partitionLevelDeletion, file.getPath(), iterator);
}
catch (IOException e)
{
sstable.markSuspect();
throw new CorruptSSTableException(e, file.getPath());
}
catch (CorruptSSTableException e) // to ensure that we marked the sstable as suspected if CorruptSSTableException is thrown from lower levels
{
sstable.markSuspect();
throw e;
}
}
public static SSTableIdentityIterator create(SSTableReader sstable, FileDataInput dfile, long dataPosition, DecoratedKey key, boolean tombstoneOnly)
{
return create(sstable, sstable.metadata(), dfile, dataPosition, key, tombstoneOnly);
}
public static SSTableIdentityIterator create(SSTableReader sstable, TableMetadata tableMetadata, FileDataInput dfile, long dataPosition, DecoratedKey key, boolean tombstoneOnly)
{
try
{
dfile.seek(dataPosition);View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Identify the file from the exception path and run `nodetool scrub` (or `sstablesplit`/verify tools) on the table so corrupt data is discarded or repaired
- Restore the affected SSTables from a backup or repair the replica via `nodetool repair` so a good copy is streamed from another node
- Check dmesg / system logs for disk errors and replace failing hardware before restarting the node
- Verify the Cassandra version that wrote the sstable matches the reading version; use upgradesstables after version upgrades
Example fix
// before: repeatedly restarting node without handling corruption // after: detect and scrub the corrupt table nodetool scrub -- keyspace table # or restore from backup / run: nodetool repair -- keyspace table
Defensive patterns
Strategy: try-catch
Validate before calling
// before reading, verify sstable components exist and pass checksum validation
// sstableverify / sstablemetadata can detect corruption up front
if (!new File(path + '-Data.db').exists()) throw new IllegalStateException('missing sstable'); Try / catch
try {
iter = SSTableIdentityIterator.create(meta, sstable, key, file, deletion);
} catch (CorruptSSTableException e) {
logger.error("Corrupt sstable {}: {}", e.getPath(), e.getCause());
// trigger scrub/repair, exclude sstable from reads
} Prevention
- Run regular `nodetool scrub` and `nodetool verify` on cold tables
- Monitor disk health (SMART) and replace degrading drives proactively
- Always stream/copy sstables with Cassandra-native tools, never raw scp
- Keep versions consistent and run upgradesstables after upgrades
- Maintain RF>1 with regular repairs so corrupt replicas can be re-replaced
When it happens
Trigger: Calling SSTableIdentityIterator.create(tableMetadata, sstable, key, file, partitionLevelDeletion) when the underlying data file throws an IOException during SSTableSimpleIterator parsing: truncated file, bad read from a compressed or uncompressed RandomAccessReader, or I/O failure from the disk during iteration setup.
Common situations: Hardware or disk failure corrupting an SSTable; manually copied or truncated SSTable files; files transferred without schema compatibility (e.g. upgrading between incompatible versions); filesystem-level corruption; reading an sstable whose compression metadata is missing or mismatched.
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
- CorruptSSTableException wrapping IOException cause for ${fil
- CorruptSSTableException (wrapped IOException from IOError, w
- Corrupt flags value for clustering prefix (isStatic flag set
- Corrupted sstable. Invalid flags found deserializing Deletio
- Failed to import sstable <filename>
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/9f97db56ed563285.
Report an issue: GitHub.