apache/cassandra · error · RuntimeException
Unable to clean up %s directory from empty %s files.
Error message
Unable to clean up %s directory from empty %s files.
What it means
During BinLog.build(), the target directory is scanned for leftover empty chronicle queue files (*.cq4 with SingleChronicleQueue.SUFFIX) that would prevent the queue from opening. If that cleanup scan itself throws (I/O errors, unreadable directory, permission problems), the original Throwable is wrapped in a RuntimeException with this message.
Source
Thrown at src/java/org/apache/cassandra/utils/binlog/BinLog.java:456
this.blocking = blocking;
return this;
}
public BinLog build(boolean cleanDirectory)
{
logger.info("Attempting to configure bin log: Path: {} Roll cycle: {} Blocking: {} Max queue weight: {} Max log size:{} Archive command: {}", path, rollCycle, blocking, maxQueueWeight, maxLogSize, archiveCommand);
synchronized (currentPaths)
{
if (currentPaths.contains(path))
throw new IllegalStateException("Already logging to " + path);
currentPaths.add(path);
}
try
{
Throwable sanitationThrowable = cleanEmptyLogFiles(new File(path), null);
if (sanitationThrowable != null)
throw new RuntimeException(format("Unable to clean up %s directory from empty %s files.",
path.toAbsolutePath(), SingleChronicleQueue.SUFFIX),
sanitationThrowable);
// create the archiver before cleaning directories - ExternalArchiver will try to archive any existing file.
BinLogArchiver archiver = Strings.isNullOrEmpty(archiveCommand) ? new DeletingArchiver(maxLogSize) : new ExternalArchiver(archiveCommand, path, maxArchiveRetries);
if (cleanDirectory)
{
logger.info("Cleaning directory: {} as requested", path);
if (new File(path).exists())
{
Throwable error = cleanDirectory(new File(path), null);
if (error != null)
{
throw new RuntimeException(error);
}
}
}
View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Check filesystem permissions and ownership of the log directory (must be writable by the Cassandra process).
- Verify the disk/mount is writable and not full (df, mount).
- Manually remove empty *.cq4 files from the directory, then re-enable the log.
- If the path points to a regular file, remove it or change the configured path.
- Restart the node after fixing storage to retry the build.
Example fix
// before (broken dir) String path = "/var/log/cassandra/fql"; // root-owned, not writable // after // chown cassandra:cassandra /var/log/cassandra/fql && rm -f /var/log/cassandra/fql/*.cq4 String path = "/var/log/cassandra/fql"; // writable; build() succeeds
Defensive patterns
Strategy: validation
Validate before calling
File dir = new File(fqlDir);
if (!dir.isDirectory() || !dir.canRead() || !dir.canWrite())
throw new IllegalStateException("BinLog dir not usable: " + dir);
dir.listFiles(f -> f.getName().endsWith(".cq4")); // probe readable listing Try / catch
try { builder.build(true); } catch (RuntimeException e) { logger.error("BinLog cleanup failed: {}", e.getCause(), e); /* alert operator to fix perms/disk */ } Prevention
- Ensure the Cassandra user owns the FQL/audit directories.
- Monitor disk space and mount health on the log volume.
- Avoid NFS or flaky storage for chronicle queue directories.
- After unclean shutdown, manually inspect the directory for stray *.cq4 files.
When it happens
Trigger: Calling BinLog.Builder.build() when cleanEmptyLogFiles(new File(path), null) throws — e.g. the log directory is not readable/writable, is on a failed mount, or contains files that cannot be inspected/deleted.
Common situations: FQL/audit log directory owned by another user or wrong permissions; disk full or read-only filesystem; NFS mount issues; corrupt/locked chronicle files left by a crash; path pointing at a file instead of a directory.
Related errors
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/a73b2a0ae2398c08.
Report an issue: GitHub.