{"record":{"id":"52cc31d3f9539e4d","repo":"apache/pulsar","slug":"dir-directory-does-not-have-read-write-privileg","errorCode":null,"errorMessage":"${dir} directory does not have read/write privilege","messagePattern":"(.+?) directory does not have read/write privilege","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"pulsar-common/src/main/java/org/apache/pulsar/common/nar/FileUtils.java","lineNumber":89,"sourceCode":"            }\n\n            return digest.digest();\n        } catch (NoSuchAlgorithmException nsae) {\n            throw new IllegalArgumentException(nsae);\n        }\n    }\n\n    public static void ensureDirectoryExistAndCanReadAndWrite(final File dir) throws IOException {\n        if (dir.exists() && !dir.isDirectory()) {\n            throw new IOException(dir.getAbsolutePath() + \" is not a directory\");\n        } else if (!dir.exists()) {\n            final boolean made = dir.mkdirs();\n            if (!made) {\n                throw new IOException(dir.getAbsolutePath() + \" could not be created\");\n            }\n        }\n        if (!(dir.canRead() && dir.canWrite())) {\n            throw new IOException(dir.getAbsolutePath() + \" directory does not have read/write privilege\");\n        }\n    }\n\n    public static void ensureDirectoryExistAndCanRead(final File dir) throws IOException {\n        if (dir.exists() && !dir.isDirectory()) {\n            throw new IOException(dir.getAbsolutePath() + \" is not a directory\");\n        } else if (!dir.exists()) {\n            final boolean made = dir.mkdirs();\n            if (!made) {\n                throw new IOException(dir.getAbsolutePath() + \" could not be created\");\n            }\n        }\n        if (!dir.canRead()) {\n            throw new IOException(dir.getAbsolutePath() + \" directory does not have read privilege\");\n        }\n    }\n\n    private static boolean deleteFile(final File file, final int attempts) {","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-common/src/main/java/org/apache/pulsar/common/nar/FileUtils.java#L71-L107","documentation":"ensureDirectoryExistAndCanReadAndWrite finishes by verifying File.canRead() && canWrite(); if either is false it throws IOException '<abs path> directory does not have read/write privilege'. This happens when the directory exists but the process user lacks read or write permission bits (or ACL/OS policy blocks access).","triggerScenarios":"The directory (existing or freshly created by a different user) has mode bits denying read or write to the process user, e.g. a root-created directory with mode 700 encountered by a non-root broker process.","commonSituations":"A previous run as root created the NAR/cache directory; shared NFS mounts exporting root-squashed permissions; hardening policies (SELinux) denying writes; umask producing restrictive modes.","solutions":["chown -R the directory to the user running the process, or chmod u+rwx on it.","Restart the service under the user that owns the directory.","Check SELinux/AppArmor audit logs and adjust policy or file context.","For NFS, fix root-squash / export permissions."],"exampleFix":"// shell fix\n// chown -R pulsar:pulsar /var/lib/pulsar/nar && chmod -R u+rwX /var/lib/pulsar/nar","handlingStrategy":"try-catch","validationCode":"if (dir.exists() && !(dir.canRead() && dir.canWrite())) {\n    throw new IllegalStateException(\"Insufficient permissions on \" + dir\n        + \": read=\" + dir.canRead() + \" write=\" + dir.canWrite());\n}","typeGuard":null,"tryCatchPattern":"try {\n    FileUtils.ensureDirectoryExistAndCanReadAndWrite(dir);\n} catch (IOException e) {\n    if (e.getMessage().contains(\"read/write privilege\")) {\n        log.error(\"Fix ownership: chown -R {}:{} {}\", serviceUser, serviceGroup, dir);\n    }\n    throw e;\n}","preventionTips":["Use a single dedicated service user and chown all data dirs to it","Check umask and provisioner default modes for created directories","Audit SELinux/AppArmor policies when running on hardened hosts"],"tags":["filesystem","permissions","io","directory"],"backgroundTag":"permission-denied","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}