apache/cassandra · error · IllegalStateException
Filesystem block size must be a power of two for Direct IO.
Error message
Filesystem block size must be a power of two for Direct IO. Block size: %d
What it means
O_DIRECT writes must be aligned to the filesystem's logical block size, and Cassandra's direct compressed writer requires that size to be a power of two to compute aligned buffer arithmetic. If FileUtils.getBlockSize() returns a value that is not a power of two, the constructor throws this IllegalStateException. Like its sibling check, the txn proxy is aborted in the catch path since the caller never gets the writer reference to clean up.
Source
Thrown at src/java/org/apache/cassandra/io/compress/DirectCompressedSequentialWriter.java:115
@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;
StorageMetrics.directWriteBufferBytes.inc(bufferSize);
StorageMetrics.directWriteBuffersAllocated.mark();
}
catch (Throwable t)View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Place the data directory on a standard filesystem with a power-of-two block size (typically 4096; ext4/xfs on regular block devices).
- Verify the reported block size with `stat -f -c %S` / `stat -c %o`; if it is non-power-of-two, change mount or device.
- Disable Direct IO for this environment (leave direct_io disabled) as the deployment target is unsupported for O_DIRECT.
Example fix
// before: fs reports blockSize=3072
throw new IllegalStateException("Filesystem block size must be a power of two for Direct IO. Block size: " + blockSize);
// after: operator moves data dir to ext4 with 4096-byte blocks
// mount -t ext4 /dev/sdX /var/lib/cassandra/data Defensive patterns
Strategy: validation
Validate before calling
long blockSize = FileUtils.getBlockSize(dataDir);
if (blockSize <= 0 || Long.bitCount(blockSize) != 1) throw new IllegalStateException("Block size not Direct-IO compatible: " + blockSize); Prevention
- Verify the mount's logical block size is a power of two (usually 4096) before enabling direct-io.
- Avoid FUSE/network filesystems for Direct IO data directories.
- Document storage requirements for Direct IO in your deployment runbook.
When it happens
Trigger: Constructing a DirectCompressedSequentialWriter on a filesystem whose reported logical block size is not a power of two (e.g. some FUSE/9p/network filesystems reporting 3072 or other odd bsize values).
Common situations: Deploying on containers or network mounts (CephFS, some FUSE drivers, odd-over-2KiB block devices) where st_blksize is an unusual value; enabling Direct IO SSTable writes on such a mount.
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
- Unable to determine filesystem block size for Direct IO. Blo
- commitlog_disk_access_mode can not be set to direct when dir
- is missing and cassandra.storagedir system property is not
- Unable check disk space in '%s'. Perhaps the Cassandra user
- ; unable to start server
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/4d9f1b3978cbdeac.
Report an issue: GitHub.