{"record":{"id":"3aa1339cca36f722","repo":"apache/cassandra","slug":"failed-to-delete-on-exit","errorCode":null,"errorMessage":"Failed to delete {} on exit","messagePattern":"Failed to delete (.+?) on exit","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/java/org/apache/cassandra/io/util/PathUtils.java","lineNumber":737,"sourceCode":"            {\n                isRegistered = true;\n            }\n            logger.trace(\"Scheduling deferred {}deletion of file: {}\", recursive ? \"recursive \" : \"\", path);\n            (recursive ? deleteRecursivelyOnExit : deleteOnExit).add(path);\n        }\n\n        public void run()\n        {\n            for (Path path : deleteOnExit)\n            {\n                try\n                {\n                    if (exists(path))\n                        delete(path);\n                }\n                catch (Throwable t)\n                {\n                    logger.warn(\"Failed to delete {} on exit\", path, t);\n                }\n            }\n            for (Path path : deleteRecursivelyOnExit)\n            {\n                try\n                {\n                    if (exists(path))\n                        deleteRecursive(path);\n                }\n                catch (Throwable t)\n                {\n                    logger.warn(\"Failed to delete {} on exit\", path, t);\n                }\n            }\n        }\n    }\n    private static final DeleteOnExit ON_EXIT = new DeleteOnExit();\n","sourceCodeStart":719,"sourceCodeEnd":755,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/io/util/PathUtils.java#L719-L755","documentation":"PathUtils registers a JVM shutdown hook (DeleteOnExit) that deletes files queued via deleteOnExitIfPossible(). If deleting a single queued file fails, it logs this warning with the path and the underlying cause. It is a best-effort cleanup notification, not a thrown error: the shutdown hook swallows the throwable and continues with the remaining queued paths.","triggerScenarios":"A path was queued with PathUtils.deleteOnExitIfPossible/deleteAsync; at JVM shutdown the hook runs and exists(path) is true but delete(path) throws (file locked, open memory-mapped segment, permission change, or the file was recreated/deleted concurrently between the exists() check and delete()).","commonSituations":"Commit-log/memtable segment files still mapped or held open by a lingering thread at shutdown; temp files in test teardown with stale file handles; directory whose permissions changed; on Windows, files locked by another process.","solutions":["Read the attached cause (t) to identify why delete failed (lock vs permissions vs race).","Ensure resources holding the file (FileHandle, RandomAccessReader, mapped segments) are closed before shutdown.","Remove the file explicitly during normal teardown instead of relying on delete-on-exit if it is recreated concurrently.","On Windows, check for antivirus/backup processes locking the file.","If harmless and recurring, suppress the specific path or downgrade handling since the JVM is exiting anyway."],"exampleFix":"// before\nFile tmp = File.createTempFile(\"hints\", \".tmp\");\nPathUtils.deleteOnExitIfPossible(tmp.toPath());\n// after\nFile tmp = File.createTempFile(\"hints\", \".tmp\");\ntry (FileOutputStream out = new FileOutputStream(tmp)) { /* use */ }\nPathUtils.delete(tmp.toPath()); // explicit deterministic cleanup instead of delete-on-exit","handlingStrategy":"try-catch","validationCode":"// before shutdown\nif (!java.nio.file.Files.isWritable(path.getParent()))\n    logger.warn(\"Path {} will not be deletable on exit\", path);","typeGuard":"static boolean deletable(java.nio.file.Path p) {\n    return java.nio.file.Files.exists(p) && java.nio.file.Files.isWritable(p.getParent()) && !java.nio.file.Files.isDirectory(p);\n}","tryCatchPattern":"try { java.nio.file.Files.deleteIfExists(path); }\ncatch (java.io.IOException e) { logger.warn(\"Failed to delete {} on exit\", path, e); }","preventionTips":["Close all file handles and mapped buffers before JVM exit (try-with-resources).","Prefer explicit deterministic cleanup in application teardown over delete-on-exit.","Check file writability/locks (esp. Windows AV scanners) for temp-file locations.","Avoid recreating files queued for deletion during shutdown."],"tags":["filesystem","shutdown","cleanup","logging"],"backgroundTag":"file-delete-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"}