{"record":{"id":"8e21f30a29748647","repo":"apache/cassandra","slug":"unable-to-create-directory","errorCode":null,"errorMessage":"Unable to create directory: ","messagePattern":"Unable to create directory: ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/commitlog/CommitLogArchiver.java","lineNumber":140,"sourceCode":"    }\n\n    @VisibleForTesting\n    static CommitLogArchiver getArchiverFromProperties(Properties commitlogCommands)\n    {\n        assert !commitlogCommands.isEmpty();\n        String archiveCommand = commitlogCommands.getProperty(\"archive_command\");\n        String restoreCommand = commitlogCommands.getProperty(\"restore_command\");\n        String restoreDirectories = commitlogCommands.getProperty(\"restore_directories\");\n        if (restoreDirectories != null && !restoreDirectories.isEmpty())\n        {\n            for (String dir : restoreDirectories.split(DELIMITER))\n            {\n                File directory = new File(dir);\n                if (!directory.exists())\n                {\n                    if (!directory.tryCreateDirectory())\n                    {\n                        throw new RuntimeException(\"Unable to create directory: \" + dir);\n                    }\n                }\n            }\n        }\n\n        String precisionPropertyValue = commitlogCommands.getProperty(\"precision\", TimeUnit.MICROSECONDS.name());\n        TimeUnit precision;\n        try\n        {\n            precision = TimeUnit.valueOf(precisionPropertyValue);\n        }\n        catch (IllegalArgumentException ex)\n        {\n            throw new RuntimeException(\"Unable to parse precision of value \" + precisionPropertyValue, ex);\n        }\n        if (precision == TimeUnit.NANOSECONDS)\n            throw new RuntimeException(\"NANOSECONDS level precision is not supported.\");\n","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/commitlog/CommitLogArchiver.java#L122-L158","documentation":"Thrown when parsing the restore_directories property of commitlog_archiving.properties: a configured restore directory does not exist and Cassandra's attempt to create it (tryCreateDirectory) failed. Restore needs the directory present so archived segments can be copied into it.","triggerScenarios":"CommitLogArchiver.getArchiverFromProperties(), called from construct(), when a path listed in restore_directories does not exist and mkdir fails (bad permissions, path is a file, unresolvable parent path).","commonSituations":"Typo in restore_directories path; parent directory missing so creation fails; path points to an existing regular file; Cassandra process lacks write permission on the parent; read-only mount in containers.","solutions":["Create the restore directory manually with correct ownership: mkdir -p <dir> && chown cassandra:cassandra <dir>.","Verify each path in restore_directories does not point to an existing regular file.","Check the parent directory grants write permission to the Cassandra process.","Correct the path in commitlog_archiving.properties if it is a typo."],"exampleFix":"# before\nrestore_directories: /nonexistent-readonly-mount/restore\n# after\nrestore_directories: /var/lib/cassandra/commitlog_restore","handlingStrategy":"validation","validationCode":"for (String dir : restoreDirs.split(\",\")) {\n    File d = new File(dir.trim());\n    if (d.exists() && !d.isDirectory()) throw new IllegalStateException(dir + \" is a file, not a directory\");\n    if (!d.exists() && !d.getParentFile().canWrite()) throw new IllegalStateException(\"cannot create \" + dir);\n}","typeGuard":null,"tryCatchPattern":"try { new CommitLogArchiver(...); }\ncatch (RuntimeException e) {\n    if (e.getMessage().startsWith(\"Unable to create directory\")) provisionDir(e); \n    throw e;\n}","preventionTips":["Pre-create restore directories with correct ownership before startup","Validate restore_directories paths after every config change","Avoid pointing restore_directories at mounts that may be absent (containers, NFS)"],"tags":["cassandra","commitlog","directory","configuration"],"backgroundTag":"mkdir-permission-denied","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"}