apache/cassandra · critical · FSReadError
FSReadError
Error message
FSReadError
What it means
CompressedSequentialWriter needs the current file channel position (e.g. to align to a compression chunk start). If the underlying FileChannel.position() call fails with an IOException, the writer wraps it in FSReadError carrying the file path, aborting the write because the on-disk position is essential to compressed chunk bookkeeping.
Source
Thrown at src/java/org/apache/cassandra/io/compress/CompressedSequentialWriter.java:179
/**
* Creates the {@link ChecksumWriter} for the chunk and full-file checksums. Invoked from the constructor,
* so overrides must not read subclass fields.
*/
protected ChecksumWriter createChecksumWriter()
{
return new ChecksumWriter(new DataOutputStream(Channels.newOutputStream(channel)));
}
@Override
public long getOnDiskFilePointer()
{
try
{
return fchannel.position();
}
catch (IOException e)
{
throw new FSReadError(e, getPath());
}
}
/**
* Get a quick estimation on how many bytes have been written to disk
*
* It should for the most part be exactly the same as getOnDiskFilePointer()
*/
@Override
public long getEstimatedOnDiskBytesWritten()
{
return chunkOffset;
}
@Override
public void flush()
{
throw new UnsupportedOperationException();View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Check the node/system logs and the wrapped IOException cause for the real OS error (EIO, EBADF, ENOSPC)
- Verify the data/commitlog disk health (dmesg, smartctl) and fix or replace the failing volume
- Run nodetool scrub/verify on affected SSTables and let failed flushes retry after the disk is healthy
- If it stems from a closed-channel bug, check for concurrent close of the writer and serialize writer lifecycle per file
Example fix
// before // disk swapped under a live node -> fchannel.position() throws IOException -> FSReadError // after // ensure stable storage and run: nodetool drain # fix/replace disk, restart Cassandra; failed SSTables recovered via scrub nodetool scrub ks tbl
Defensive patterns
Strategy: retry
Validate before calling
// Before writes, verify the data volume is healthy and writable Files.isWritable(Paths.get(cassandraDataDir)); # dmesg | grep -i 'I/O error'
Try / catch
try {
writer.getOnDiskFilePointer();
} catch (FSReadError e) {
logger.error("Channel position failed for {}", e.getPath(), e.getCause());
// fail the write; let Cassandra's flush executor retry after disk recovery
} Prevention
- Monitor disk health proactively (SMART metrics) on data volumes
- Never close or swap files under a live writer concurrently
- Set alerts for ENOSPC and I/O errors well before capacity is exhausted
- Use redundant/failure-tested storage for SSTable directories
When it happens
Trigger: Calling getOnDiskFilePointer()/seekToChunkStart() on a CompressedSequentialWriter whose file channel is broken: disk I/O error, file descriptor closed or invalidated (e.g. disk replaced, handle closed by another thread), or an OS-level error reading the channel's offset.
Common situations: Disk hardware failures or full/failed volumes during compaction or memtable flush; file handles closed unexpectedly after a disk swap; container environments where the storage backing SSTables becomes unavailable mid-write.
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/e8d63225d6b90347.
Report an issue: GitHub.