{"record":{"id":"9b3a21a4a9f90ea7","repo":"apache/pulsar","slug":"dir-is-not-a-directory","errorCode":null,"errorMessage":"${dir} is not a directory","messagePattern":"(.+?) is not a directory","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"pulsar-common/src/main/java/org/apache/pulsar/common/nar/FileUtils.java","lineNumber":81,"sourceCode":"            final MessageDigest digest = MessageDigest.getInstance(\"SHA-256\");\n\n            final byte[] buffer = new byte[8192];\n            int read = inputStream.read(buffer);\n\n            while (read > -1) {\n                digest.update(buffer, 0, read);\n                read = inputStream.read(buffer);\n            }\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\");","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-common/src/main/java/org/apache/pulsar/common/nar/FileUtils.java#L63-L99","documentation":"FileUtils.ensureDirectoryExistAndCanReadAndWrite(dir) prepares a directory that must exist and be readable/writable. If the File exists but is a regular file (or other non-directory), it throws IOException '<abs path> is not a directory' because a file occupies the path where a directory is required. It will happily create the directory if missing, but never overwrite an existing file.","triggerScenarios":"Passing a File whose path already exists as a regular file (or symlink to a file) to ensureDirectoryExistAndCanReadAndWrite.","commonSituations":"NAR extraction/cache directories (e.g. the narExtractBundleDirectory config) pointing at a path where a stale file was created earlier, a previous misconfiguration wrote a file at the expected directory path, or a container mount maps a file instead of a directory.","solutions":["Inspect the path (ls -la) and remove or rename the file occupying it, then retry so the code can mkdirs.","Fix the configuration property pointing at this path so it names a dedicated directory.","In containers/orchestrators, mount a volume/directory, not a single file, at that path."],"exampleFix":"// before\nFile dir = new File(config.getNarDir()); // path is a leftover file\nFileUtils.ensureDirectoryExistAndCanReadAndWrite(dir);\n// after\nFile dir = new File(config.getNarDir());\nif (dir.exists() && !dir.isDirectory()) {\n    dir.delete(); // or move it aside\n}\nFileUtils.ensureDirectoryExistAndCanReadAndWrite(dir);","handlingStrategy":"validation","validationCode":"File dir = new File(path);\nif (dir.exists() && !dir.isDirectory()) {\n    throw new IllegalStateException(\"Path is a file, expected directory: \" + path);\n}","typeGuard":null,"tryCatchPattern":"try {\n    FileUtils.ensureDirectoryExistAndCanReadAndWrite(dir);\n} catch (IOException e) {\n    // e.getMessage() ends with 'is not a directory' -> move file aside or fail config\n    throw new IllegalStateException(\"Fix path \" + dir + \": \" + e.getMessage(), e);\n}","preventionTips":["Check the configured path with ls -la at startup and fail fast with a clear message","Dedicate separate paths for files and directories in config","In containers, mount volumes as directories at these paths"],"tags":["filesystem","io","directory","nar"],"backgroundTag":"path-is-not-a-directory","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"}