{"record":{"id":"80773e7b32a0548c","repo":"apache/pulsar","slug":"failed-to-create-parent-dirs-for-path","errorCode":null,"errorMessage":"Failed to create parent dirs for ${path}","messagePattern":"Failed to create parent dirs for (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"pulsar-package-management/filesystem-storage/src/main/java/org/apache/pulsar/packages/management/storage/filesystem/FileSystemPackagesStorage.java","lineNumber":72,"sourceCode":"        if (storagePath != null) {\n            this.storagePath = new File(storagePath);\n        } else {\n            this.storagePath = new File(DEFAULT_STORAGE_PATH);\n        }\n    }\n\n    private File getPath(String path) throws IOException {\n        // Normalize the path to remove any redundant path elements\n        File f = Paths.get(storagePath.toString(), path).normalize().toFile();\n\n        // Ensure the normalized path is still within the storagePath\n        if (!f.getAbsolutePath().startsWith(storagePath.getAbsolutePath())) {\n            throw new IOException(\"Invalid path: \" + path);\n        }\n\n        if (!f.getParentFile().exists()) {\n            if (!f.getParentFile().mkdirs()) {\n                throw new RuntimeException(\"Failed to create parent dirs for \" + path);\n            }\n        }\n        return f;\n    }\n\n    @Override\n    public void initialize() {\n        if (!storagePath.exists()) {\n            if (!storagePath.mkdirs()) {\n                throw new RuntimeException(\"Failed to create base storage directory at \" + storagePath);\n            }\n        }\n\n        log.info().attr(\"storagePath\", storagePath).log(\"Packages management filesystem storage initialized\");\n    }\n\n    @Override\n    public CompletableFuture<Void> writeAsync(String path, InputStream inputStream) {","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-package-management/filesystem-storage/src/main/java/org/apache/pulsar/packages/management/storage/filesystem/FileSystemPackagesStorage.java#L54-L90","documentation":"getPath creates parent directories for the requested file if they do not exist; when File.mkdirs() returns false (cannot create the directories), a RuntimeException is thrown naming the path. This typically reflects a filesystem-level problem: permissions, read-only volume, or the parent being an existing regular file.","triggerScenarios":"Any storage operation (read/write/delete/list/exists) whose target file's parent directory does not exist and cannot be created: storagePath on a read-only mount, insufficient OS permissions, or a file already occupying the parent path.","commonSituations":"Running the broker as a user without write access to the storage directory; disk mounted read-only after failure; leftover file where a directory was expected; full disk or quota exhaustion.","solutions":["Check OS permissions on the storage directory and the broker process user; chown/chmod so the process can write.","Ensure no regular file exists at the parent path that should be a directory; remove or rename it.","Verify the volume is writable (not read-only) and has free space/inodes.","Pre-create the directory hierarchy manually, then retry the operation."],"exampleFix":"# before: permission denied -> RuntimeException\nsudo chown -R pulsar:pulsar /data/pulsar/packages\n# after: storage writable, getPath can mkdirs successfully","handlingStrategy":"validation","validationCode":"java.io.File parent = java.nio.file.Paths.get(storageRoot, path).normalize().toFile().getParentFile();\nboolean creatable = parent.exists() || (parent.canWrite() || parent.getParentFile().canWrite());","typeGuard":null,"tryCatchPattern":"try {\n    storage.readAsync(path).get();\n} catch (java.util.concurrent.ExecutionException e) {\n    if (e.getCause() instanceof RuntimeException && e.getCause().getMessage().startsWith(\"Failed to create parent dirs\")) {\n        log.error(\"Storage dir unwritable for {}: fix permissions/mount\", path, e.getCause());\n    }\n    throw e;\n}","preventionTips":["Run the broker process as a user with write access to the storage root.","Ensure the storage volume is writable with free space and inodes.","Never place a regular file where a parent directory is expected.","Pre-provision the directory layout during deployment."],"tags":["filesystem","io","permissions","storage"],"backgroundTag":"mkdir-failed-permission-denied","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}