apache/cassandra · critical · FSReadError

Failed to read from

Error message

Failed to read from 

What it means

TableRecordIterator.advance reads the current journal record row from the merged system.journal table view; any Throwable during that read is wrapped in FSReadError with the message 'Failed to read from ' + unmerged (the underlying table/iterator name). It signals a low-level storage failure while iterating Accord journal records.

Solutions

  1. Check the wrapped cause (getCause()) and node logs to identify the failing sstable or file.
  2. Run nodetool scrub or repair on the system.journal table, or restore the affected files from a good backup.
  3. Check disk health (dmesg/SMART) and free space on the data volume.
  4. Replace the corrupted node from a replica/rebuild if corruption persists.
Defensive patterns

Strategy: try-catch

Try / catch

try { while (it.advance()) { ... } } catch (FSReadError e) { LOG.error("Journal read failed from {}: {}", e.getMessage(), e.getCause(), e); /* inspect cause: sstable corruption / disk failure */ }

Prevention

When it happens

Trigger: Calling advance() on the iterator when the underlying storage engine cannot read the row (corrupt sstable, missing file, failed read at the storage layer).

Common situations: Disk corruption or failing hardware; sstables deleted/corrupted under a running node; filesystem errors on the data directory; restoring partial backups while the node is running.

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/82fb431fae213722. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/service/accord/journal/TableRecordIterator.java:121

    }

    boolean advance()
    {
        if (merged == null || !merged.hasNext())
            return false;

        try
        {
            Row row = (Row) merged.next();
            segment = LongType.instance.compose(ByteBuffer.wrap((byte[]) row.clustering().get(0)));
            offset = Int32Type.instance.compose(ByteBuffer.wrap((byte[]) row.clustering().get(1)));
            value = row.getCell(AccordKeyspace.JournalColumns.record).buffer();
            userVersion = Int32Type.instance.compose(row.getCell(AccordKeyspace.JournalColumns.user_version).buffer());
            return true;
        }
        catch (Throwable t)
        {
            throw new FSReadError("Failed to read from " + unmerged, t);
        }
    }

    @Override
    public void close()
    {
        if (merged != null)
            merged.close();
    }
}

View on GitHub (pinned to 88fd0f6a0e)