apache/cassandra · critical · CorruptSSTableException

CorruptSSTableException wrapping IOException cause for ${fil

Error message

CorruptSSTableException wrapping IOException cause for ${filename}

What it means

When iteration hits an IOError whose cause is an IOException, SSTableIdentityIterator.hasNext() treats it as disk-level corruption: it marks the sstable suspect and rethrows the cause wrapped in a CorruptSSTableException with the sstable filename. IErrors with other causes are rethrown unchanged.

Source

Thrown at src/java/org/apache/cassandra/io/sstable/SSTableIdentityIterator.java:207

        {
            return iterator.hasNext();
        }
        catch (IndexOutOfBoundsException | VIntOutOfRangeException | AssertionError e)
        {
            sstable.markSuspect();
            throw new CorruptSSTableException(e, filename);
        }
        catch (CorruptSSTableException e) // to ensure that we marked the sstable as suspected if CorruptSSTableException is thrown from lower levels
        {
            sstable.markSuspect();
            throw e;
        }
        catch (IOError e)
        {
            if (e.getCause() instanceof IOException)
            {
                sstable.markSuspect();
                throw new CorruptSSTableException((Exception)e.getCause(), filename);
            }
            else
            {
                throw e;
            }
        }
    }

    public Unfiltered next()
    {
        try
        {
            if (isClosed)
                throw new IllegalStateException("Iterator used after closing.");

            return doCompute();
        }
        catch (IndexOutOfBoundsException | VIntOutOfRangeException | AssertionError e)

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Scrub the table with `nodetool scrub` to handle the corrupt sstable named in the exception
  2. Restore the sstable from backup or run `nodetool repair` to re-stream healthy data from replicas
  3. Check dmesg/filesystem logs for I/O errors and fix or replace the failing disk
  4. Ensure no external process is modifying or removing sstable files while Cassandra runs

Example fix

// before: leaving node in a failing state
// after: scrub corrupt table and repair data
nodetool scrub -- keyspace table
nodetool repair -- keyspace table
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure the file is intact and accessible before iterating
if (!new File(filename).exists()) throw new IllegalStateException('sstable missing');
// run nodetool verify / sstable checksums to pre-validate

Try / catch

try {
    while (iter.hasNext()) { consume(iter.next()); }
} catch (CorruptSSTableException e) {
    logger.error("Read failed on sstable {}: {}", e.getPath(), e.getCause());
    // retry on another replica; schedule scrub/repair
} catch (IOError e) {
    // non-IOException cause: surface as infrastructure failure
    throw e;
}

Prevention

When it happens

Trigger: Calling hasNext() when the underlying file reader (e.g. RandomAccessReader) throws org.apache.cassandra.io.util.IOError caused by an IOException during row reads — disk read failure, file truncated beneath the reader, or compressed-file read error.

Common situations: Disk failure or bad sectors encountered mid-scan; sstable file deleted or truncated while queries run; storage-layer errors (NFS, EBS) surfacing as IOExceptions; corrupted compression metadata.

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


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/161bccce75d85b8a. Report an issue: GitHub.