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

  1. Check the target disk for free space (df -h) and fix ENOSPC; clean or expand storage, then retry streaming
  2. 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
  3. 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
  4. 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

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


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