apache/cassandra · critical · FSWriteError
FSWriteError (wraps IOException writing sstable component)
Error message
FSWriteError (wraps IOException writing sstable component)
What it means
FSWriteError is Cassandra's wrapper for any IOException raised while writing an sstable component to local disk. In SSTableZeroCopyWriter.write (src/java/org/apache/cassandra/io/sstable/SSTableZeroCopyWriter.java:119), a failure reading from the inbound stream or writing/flushing the component writer is rethrown as FSWriteError carrying the underlying IOException and the target file path, so it participates in the disk-failure policy machinery.
Source
Thrown at src/java/org/apache/cassandra/io/sstable/SSTableZeroCopyWriter.java:119
{
final int BUFFER_SIZE = 1 << 20;
long bytesRead = 0;
byte[] buff = new byte[BUFFER_SIZE];
try
{
while (bytesRead < size)
{
int toRead = (int) Math.min(size - bytesRead, BUFFER_SIZE);
in.readFully(buff, 0, toRead);
int count = Math.min(toRead, BUFFER_SIZE);
out.write(buff, 0, count);
bytesRead += count;
}
out.sync(); // finish will also call sync(). Leaving here to get stuff flushed as early as possible
}
catch (IOException e)
{
throw new FSWriteError(e, out.getFile());
}
}
@Override
public void append(UnfilteredRowIterator partition)
{
throw new UnsupportedOperationException();
}
@Override
public Collection<SSTableReader> finish(boolean openResult)
{
setOpenResult(openResult);
for (ZeroCopySequentialWriter writer : componentWriters.values())
writer.finish();
return finished();View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Check the target disk for free space (df -h) and fix ENOSPC; clean or expand storage, then retry streaming
- Inspect the underlying IOException cause in the FSWriteError for the file path and hardware errors; check dmesg/journal for disk errors and replace failing media
- If the cause is a read/EOF from the peer, treat it as a streaming/connection issue rather than local disk failure and retry the stream
- If triggered via the unit-test path (in not AsyncStreamingInputPlus), switch to the zero-copy AsyncStreamingInputPlus path or fix the test harness
Example fix
// before
try {
writer.writeComponent(component, in, size);
} catch (FSWriteError e) {
logger.error("disk write failed", e); // masks the real cause
}
// after
try {
writer.writeComponent(component, in, size);
} catch (FSWriteError e) {
if (e.getCause() instanceof EOFException) {
logger.warn("stream truncated by peer, will re-stream", e);
} else {
throw e; // let disk failure policy handle real disk errors
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// ensure target disk can accept the component before writing
if (new File(file.getParent()).getUsableSpace() < size) throw new IOException("insufficient space for " + file); Try / catch
try {
writeComponent(component, in, size);
} catch (FSWriteError e) {
Throwable cause = e.getCause();
if (cause instanceof EOFException) { /* truncated stream: reconnect and re-stream */ }
else { /* disk error: let disk failure policy decide */ throw e; }
} Prevention
- Keep data disks under capacity thresholds to absorb streamed components
- Track FSWriteError occurrences and correlate causes (ENOSPC vs EIO) in monitoring
- Use stable network conditions for streaming to avoid mid-transfer read failures
When it happens
Trigger: An IOException during writeComponent -> write: the source DataInputPlus (e.g. AsyncStreamingInputPlus) hits EOF or a read error mid-stream, the local disk write or out.sync() fails (ENOSPC, EIO), or the output channel is closed while the non-production byte[]-copy path (unit-test path) is used.
Common situations: Target disk full or removed mid-streaming during zero-copy streaming of a component; network/stream peer disconnects causing a truncated read that surfaces as an I/O error; running the non-zero-copy fallback path where buffer writes fail; disk failure policy triggering on a node receiving streamed sstables.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- Corrupt flags value for clustering prefix (isStatic flag set
- SyncException (wraps IOException from disk writer flush/sync
- Failed to save Bloom filter for SSTable:
- Failed to save index summary to
- max_space_usable_for_compactions_in_percentage must be betwe
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/1f25968145ddcfe0.
Report an issue: GitHub.