{"record":{"id":"a73b2a0ae2398c08","repo":"apache/cassandra","slug":"unable-to-clean-up-s-directory-from-empty-s-file","errorCode":null,"errorMessage":"Unable to clean up %s directory from empty %s files.","messagePattern":"Unable to clean up (.+?) directory from empty (.+?) files\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/utils/binlog/BinLog.java","lineNumber":456,"sourceCode":"            this.blocking = blocking;\n            return this;\n        }\n\n\n        public BinLog build(boolean cleanDirectory)\n        {\n            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);\n            synchronized (currentPaths)\n            {\n                if (currentPaths.contains(path))\n                    throw new IllegalStateException(\"Already logging to \" + path);\n                currentPaths.add(path);\n            }\n            try\n            {\n                Throwable sanitationThrowable = cleanEmptyLogFiles(new File(path), null);\n                if (sanitationThrowable != null)\n                    throw new RuntimeException(format(\"Unable to clean up %s directory from empty %s files.\",\n                                                      path.toAbsolutePath(), SingleChronicleQueue.SUFFIX),\n                                               sanitationThrowable);\n\n                // create the archiver before cleaning directories - ExternalArchiver will try to archive any existing file.\n                BinLogArchiver archiver = Strings.isNullOrEmpty(archiveCommand) ? new DeletingArchiver(maxLogSize) : new ExternalArchiver(archiveCommand, path, maxArchiveRetries);\n                if (cleanDirectory)\n                {\n                    logger.info(\"Cleaning directory: {} as requested\", path);\n                    if (new File(path).exists())\n                    {\n                        Throwable error = cleanDirectory(new File(path), null);\n                        if (error != null)\n                        {\n                            throw new RuntimeException(error);\n                        }\n                    }\n                }\n","sourceCodeStart":438,"sourceCodeEnd":474,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/utils/binlog/BinLog.java#L438-L474","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (broken dir)\nString path = \"/var/log/cassandra/fql\"; // root-owned, not writable\n// after\n// chown cassandra:cassandra /var/log/cassandra/fql && rm -f /var/log/cassandra/fql/*.cq4\nString path = \"/var/log/cassandra/fql\"; // writable; build() succeeds","handlingStrategy":"validation","validationCode":"File dir = new File(fqlDir);\nif (!dir.isDirectory() || !dir.canRead() || !dir.canWrite())\n    throw new IllegalStateException(\"BinLog dir not usable: \" + dir);\ndir.listFiles(f -> f.getName().endsWith(\".cq4\")); // probe readable listing","typeGuard":null,"tryCatchPattern":"try { builder.build(true); } catch (RuntimeException e) { logger.error(\"BinLog cleanup failed: {}\", e.getCause(), e); /* alert operator to fix perms/disk */ }","preventionTips":["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."],"tags":["logging","filesystem","io"],"backgroundTag":"file-cleanup-failed","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}