{"record":{"id":"1f25968145ddcfe0","repo":"apache/cassandra","slug":"fswriteerror-wraps-ioexception-writing-sstable-co","errorCode":null,"errorMessage":"FSWriteError (wraps IOException writing sstable component)","messagePattern":"FSWriteError \\(wraps IOException writing sstable component\\)","errorType":"exception","errorClass":"FSWriteError","httpStatus":null,"severity":"critical","filePath":"src/java/org/apache/cassandra/io/sstable/SSTableZeroCopyWriter.java","lineNumber":119,"sourceCode":"    {\n        final int BUFFER_SIZE = 1 << 20;\n        long bytesRead = 0;\n        byte[] buff = new byte[BUFFER_SIZE];\n        try\n        {\n            while (bytesRead < size)\n            {\n                int toRead = (int) Math.min(size - bytesRead, BUFFER_SIZE);\n                in.readFully(buff, 0, toRead);\n                int count = Math.min(toRead, BUFFER_SIZE);\n                out.write(buff, 0, count);\n                bytesRead += count;\n            }\n            out.sync(); // finish will also call sync(). Leaving here to get stuff flushed as early as possible\n        }\n        catch (IOException e)\n        {\n            throw new FSWriteError(e, out.getFile());\n        }\n    }\n\n    @Override\n    public void append(UnfilteredRowIterator partition)\n    {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public Collection<SSTableReader> finish(boolean openResult)\n    {\n        setOpenResult(openResult);\n\n        for (ZeroCopySequentialWriter writer : componentWriters.values())\n            writer.finish();\n\n        return finished();","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/io/sstable/SSTableZeroCopyWriter.java#L101-L137","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\ntry {\n    writer.writeComponent(component, in, size);\n} catch (FSWriteError e) {\n    logger.error(\"disk write failed\", e); // masks the real cause\n}\n// after\ntry {\n    writer.writeComponent(component, in, size);\n} catch (FSWriteError e) {\n    if (e.getCause() instanceof EOFException) {\n        logger.warn(\"stream truncated by peer, will re-stream\", e);\n    } else {\n        throw e; // let disk failure policy handle real disk errors\n    }\n}","handlingStrategy":"try-catch","validationCode":"// ensure target disk can accept the component before writing\nif (new File(file.getParent()).getUsableSpace() < size) throw new IOException(\"insufficient space for \" + file);","typeGuard":null,"tryCatchPattern":"try {\n    writeComponent(component, in, size);\n} catch (FSWriteError e) {\n    Throwable cause = e.getCause();\n    if (cause instanceof EOFException) { /* truncated stream: reconnect and re-stream */ }\n    else { /* disk error: let disk failure policy decide */ throw e; }\n}","preventionTips":["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"],"tags":["cassandra","sstable","io","disk","streaming"],"backgroundTag":"file-write-failed","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}