apache/cassandra · error · IllegalStateException
Unable to determine filesystem block size for Direct IO. Blo
Error message
Unable to determine filesystem block size for Direct IO. Block size: %d
What it means
DirectCompressedSequentialWriter opens an O_DIRECT channel and must know the filesystem's logical block size to do aligned direct I/O. During construction it calls FileUtils.getBlockSize() on the file's parent directory; if the OS returns a non-positive value, the writer aborts with this IllegalStateException. The constructor deliberately throws inside its try block because the caller never receives the writer reference needed to clean up the already-opened channel and buffers, so the txn proxy is aborted in the catch path.
Source
Thrown at src/java/org/apache/cassandra/io/compress/DirectCompressedSequentialWriter.java:111
private int directBufferBytes = 0;
public DirectCompressedSequentialWriter(File file,
File offsetsFile,
@Nullable File digestFile,
SequentialWriterOption option,
CompressionParams parameters,
MetadataCollector sstableMetadataCollector,
@Nullable CompressionDictionaryManager compressionDictionaryManager)
{
super(file, offsetsFile, digestFile, option, parameters, sstableMetadataCollector, compressionDictionaryManager, ExtendedOpenOption.DIRECT);
// super() opened the O_DIRECT FileChannel and allocated parent buffers; if anything below throws
// the caller never gets a reference to clean them up, so abort the txn proxy ourselves.
try
{
this.blockSize = FileUtils.getBlockSize(file.parent());
if (blockSize <= 0)
throw new IllegalStateException("Unable to determine filesystem block size for Direct IO. " +
"Block size: " + blockSize);
if (!BitUtil.isPowerOfTwo(blockSize))
throw new IllegalStateException("Filesystem block size must be a power of two for Direct IO. " +
"Block size: " + blockSize);
int configuredSize = DatabaseDescriptor.getDirectWriteBufferSize().toBytes();
int maxChunkWrite = parameters.getSstableCompressor().initialCompressedBufferLength(parameters.chunkLength());
int minRequiredSize = maxChunkWrite + CRC_LENGTH + blockSize;
if (configuredSize < minRequiredSize && undersizedBufferWarned.compareAndSet(false, true))
logger.warn("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.",
configuredSize, file, maxChunkWrite, blockSize, minRequiredSize);
int bufferSize = BitUtil.align(Math.max(configuredSize, minRequiredSize), blockSize);
this.writeBuffer = BufferUtil.allocateDirectAligned(bufferSize, blockSize);
this.directBufferBytes = bufferSize;View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Move the data directory to a filesystem that reports a valid, positive logical block size (ext4, xfs, etc.).
- Check with `stat -f` or `stat -c %o` on the data directory what block size the kernel reports; if it is 0, the filesystem does not support Direct IO properly.
- Disable the direct-io write path (do not enable Direct IO SSTable writing) if the storage layer cannot support it.
Example fix
// before: node with direct-io enabled on a filesystem reporting blksize 0
throw new IllegalStateException("Unable to determine filesystem block size for Direct IO. Block size: " + blockSize);
// after (operator action): relocate data dir to a direct-io capable fs
// cassandra.yaml / table option: direct_io = false (or mount ext4/xfs) Defensive patterns
Strategy: validation
Validate before calling
long blockSize = FileUtils.getBlockSize(Paths.get(dataDir).toFile());
if (blockSize <= 0) throw new IllegalStateException("Direct IO unsupported on " + dataDir + ": block size " + blockSize); Prevention
- Check `stat -c %o <dataDir>` returns a positive power-of-two value before enabling direct-io.
- Run direct IO only on proven filesystems (ext4, xfs on local block devices).
- Smoke-test Direct IO SSTable writes in staging on the same storage stack as production.
When it happens
Trigger: Creating a Direct-IO compressed SSTable writer (DirectCompressedSequentialWriter public constructor) on a filesystem whose st_blksize (f_bsize) cannot be determined or is reported as <= 0 by FileUtils.getBlockSize(file.parent()).
Common situations: Running on exotic/unsupported filesystems (e.g. tmpfs configurations, FUSE mounts, some network filesystems) that report a zero or nonsensical block size; enabling the direct-io option in an environment where statvfs reports unusable values.
Understand the failure class
Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.
Related errors
- Filesystem block size must be a power of two for Direct IO.
- commitlog_disk_access_mode can not be set to direct when dir
- Unable check disk space in '%s'. Perhaps the Cassandra user
- ; unable to start server
- direct_write_buffer_size must be > 0 when background_write_d
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/5e3fbcb9baec6c6b.
Report an issue: GitHub.