{"record":{"id":"a7fdd44c1b4ae6dd","repo":"apache/cassandra","slug":"direct-write-buffer-size-bytes-is-below-the-m","errorCode":null,"errorMessage":"direct_write_buffer_size ({} bytes) is below the minimum required for SSTable {} (worst-case chunk {} + CRC 4 + blockSize {} = {} bytes); using the minimum. Increase direct_write_buffer_size in cassandra.yaml to silence this warning.","messagePattern":"direct_write_buffer_size \\((.+?) bytes\\) is below the minimum required for SSTable (.+?) \\(worst-case chunk (.+?) \\+ CRC 4 \\+ blockSize (.+?) = (.+?) bytes\\); using the minimum\\. Increase direct_write_buffer_size in cassandra\\.yaml to silence this warning\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/java/org/apache/cassandra/io/compress/DirectCompressedSequentialWriter.java","lineNumber":122,"sourceCode":"\n        // super() opened the O_DIRECT FileChannel and allocated parent buffers; if anything below throws\n        // the caller never gets a reference to clean them up, so abort the txn proxy ourselves.\n        try\n        {\n            this.blockSize = FileUtils.getBlockSize(file.parent());\n            if (blockSize <= 0)\n                throw new IllegalStateException(\"Unable to determine filesystem block size for Direct IO. \" +\n                                                \"Block size: \" + blockSize);\n\n            if (!BitUtil.isPowerOfTwo(blockSize))\n                throw new IllegalStateException(\"Filesystem block size must be a power of two for Direct IO. \" +\n                                                \"Block size: \" + blockSize);\n\n            int configuredSize = DatabaseDescriptor.getDirectWriteBufferSize().toBytes();\n            int maxChunkWrite = parameters.getSstableCompressor().initialCompressedBufferLength(parameters.chunkLength());\n            int minRequiredSize = maxChunkWrite + CRC_LENGTH + blockSize;\n            if (configuredSize < minRequiredSize && undersizedBufferWarned.compareAndSet(false, true))\n                logger.warn(\"direct_write_buffer_size ({} bytes) is below the minimum required for SSTable {} \" +\n                            \"(worst-case chunk {} + CRC 4 + blockSize {} = {} bytes); using the minimum. \" +\n                            \"Increase direct_write_buffer_size in cassandra.yaml to silence this warning.\",\n                            configuredSize, file, maxChunkWrite, blockSize, minRequiredSize);\n            int bufferSize = BitUtil.align(Math.max(configuredSize, minRequiredSize), blockSize);\n\n            this.writeBuffer = BufferUtil.allocateDirectAligned(bufferSize, blockSize);\n            this.directBufferBytes = bufferSize;\n            StorageMetrics.directWriteBufferBytes.inc(bufferSize);\n            StorageMetrics.directWriteBuffersAllocated.mark();\n        }\n        catch (Throwable t)\n        {\n            Throwable merged = t;\n            try { merged = abort(t); }\n            catch (Throwable t2) { t.addSuppressed(t2); }\n            Throwables.maybeFail(merged);\n            // Unreachable: maybeFail(non-null) always throws. Present for definite-assignment of `blockSize`.\n            throw new AssertionError(\"Throwables.maybeFail should have thrown\", merged);","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/io/compress/DirectCompressedSequentialWriter.java#L104-L140","documentation":"DirectCompressedSequentialWriter validates that the configured direct_write_buffer_size can hold the worst-case compressed chunk plus CRC bytes and blockSize alignment. When it is too small, the writer clamps the buffer up to the computed minimum and logs this warning once (guarded by an AtomicBoolean CAS) telling the operator to raise the yaml setting.","triggerScenarios":"DatabaseDescriptor.getDirectWriteBufferSize() < initialCompressedBufferLength(chunkLength) + 4 (CRC) + blockSize for the sstable's compressor; occurs when creating a direct-IO compressed sequential writer for a memtable flush/streaming write.","commonSituations":"Operators lowered direct_write_buffer_size in cassandra.yaml to save memory; large chunk_length_in_kb with a compressor that can inflate data (worst-case size exceeds input); high blockSize making min required size larger than expected.","solutions":["Increase direct_write_buffer_size in cassandra.yaml to at least the reported minRequiredSize and restart","Reduce chunk_length_in_kb in the table's compression options so the worst-case chunk fits the current buffer","Ignore the warning if the automatic clamping is acceptable — writes still work with the minimum-sized buffer"],"exampleFix":"// before (cassandra.yaml)\ndirect_write_buffer_size: 128KiB\n// after — must exceed worst-case chunk + CRC(4) + blockSize\ndirect_write_buffer_size: 1MiB","handlingStrategy":"validation","validationCode":"// Pre-check before enabling direct-IO compressed writes:\nint min = compressor.initialCompressedBufferLength(chunkLength) + 4 + blockSize;\nif (DatabaseDescriptor.getDirectWriteBufferSize().toBytes() < min)\n    throw new IllegalStateException(\"Increase direct_write_buffer_size to >= \" + min);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set direct_write_buffer_size >= chunk_length worst case + CRC + blockSize for your largest compressed table","Re-evaluate the setting whenever chunk_length_in_kb or compressor changes","Watch startup logs for this warning after config changes"],"tags":["compression","direct-io","configuration","buffer-size"],"backgroundTag":"value-out-of-range","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}