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

  1. Move the data directory to a filesystem that reports a valid, positive logical block size (ext4, xfs, etc.).
  2. 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.
  3. 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

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


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