{"record":{"id":"8cbcd896e5b5e256","repo":"apache/druid","slug":"cannot-create-directory-s","errorCode":null,"errorMessage":"Cannot create directory [%s]","messagePattern":"Cannot create directory \\[(.+?)\\]","errorType":"exception","errorClass":"IOE","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/java/util/common/FileUtils.java","lineNumber":513,"sourceCode":"    }\n  }\n\n  /**\n   * Create \"directory\" and all intermediate directories as needed. If the directory is successfully created, or already\n   * exists, returns quietly. Otherwise, throws an IOException.\n   *\n   * Simpler to use than {@link File#mkdirs()}, and more reliable since it is safe from races where two threads try\n   * to create the same directory at the same time.\n   *\n   * The name is inspired by UNIX {@code mkdir -p}, which has the same behavior.\n   */\n  @SuppressForbidden(reason = \"File#mkdirs\")\n  public static void mkdirp(final File directory) throws IOException\n  {\n    // isDirectory check after mkdirs is necessary in case of concurrent calls to mkdirp, because two concurrent\n    // calls to mkdirs cannot both succeed.\n    if (!directory.mkdirs() && !directory.isDirectory()) {\n      throw new IOE(\"Cannot create directory [%s]\", directory);\n    }\n  }\n\n  /**\n   * Equivalent to {@link org.apache.commons.io.FileUtils#deleteDirectory(File)}. Exists here mostly so callers\n   * can avoid dealing with our FileUtils and the Commons FileUtils having the same name.\n   */\n  @SuppressForbidden(reason = \"FilesUtils#deleteDirectory\")\n  public static void deleteDirectory(final File directory) throws IOException\n  {\n    org.apache.commons.io.FileUtils.deleteDirectory(directory);\n  }\n\n  /**\n   * Deletes {@code directory} (recursively, like {@link #deleteDirectory(File)}), then walks up deleting each\n   * now-empty ancestor directory, stopping at the first non-empty ancestor or when {@code stopAt} is reached,\n   * whichever comes first. {@code stopAt} itself is never deleted, so callers can pass a base directory that must\n   * survive.","sourceCodeStart":495,"sourceCodeEnd":531,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/java/util/common/FileUtils.java#L495-L531","documentation":"FileUtils.mkdirp throws this IOException when File.mkdirs() fails and the directory still does not exist afterwards. Because two concurrent mkdirs calls cannot both succeed, the code tolerates races via the isDirectory() check; this error means creation genuinely failed (permissions, path component issues, etc.).","triggerScenarios":"Calling FileUtils.mkdirp(directory) where some path component is missing and cannot be created, the target or an intermediate component is a regular file, or the OS denies creation permissions.","commonSituations":"First startup with segment cache or task dirs on a path the druid user cannot create; a stale file occupying the directory path; typo'd directory configuration creating deeply nested invalid paths; read-only volume.","solutions":["Check permissions on each path component and create the parent chain manually if needed","Verify no regular file exists at the target path; remove or rename it","Ensure the process user owns or can write to the parent directory","Catch the IOException and fall back to an alternate configured directory","Re-check the configured path for typos (e.g. wrong mount point)"],"exampleFix":"// before\nFileUtils.mkdirp(new File(\"/druid/segment-cache\")); // /druid owned by root\n// after\nFiles.createDirectories(Paths.get(\"/druid/segment-cache\")); // pre-created with correct owner\nFileUtils.mkdirp(new File(\"/druid/segment-cache\"));","handlingStrategy":"try-catch","validationCode":"File dir = new File(path);\nFile parent = dir.getAbsoluteFile().getParentFile();\nif (parent != null && !parent.canWrite()) throw new IllegalStateException(\"Cannot create \" + path + \": parent not writable\");\nif (dir.isFile()) throw new IllegalStateException(\"Path is a file, not a directory: \" + path);","typeGuard":"static boolean canMkdirp(File dir) {\n  return dir != null && !dir.isFile()\n    && (dir.isDirectory() || (dir.getAbsoluteFile().getParentFile() != null && dir.getAbsoluteFile().getParentFile().canWrite()));\n}","tryCatchPattern":"try {\n  FileUtils.mkdirp(dir);\n} catch (IOException e) {\n  throw new RuntimeException(\"Failed to create directory \" + dir + \": \" + e.getMessage(), e);\n}","preventionTips":["Pre-create the parent directory chain at provisioning/deployment time with correct ownership","Ensure no stray regular file occupies the target path","Run the service under a user that owns or can write to the parent directory","Handle concurrent startup races — mkdirp tolerates them, but permission errors do not resolve themselves"],"tags":["filesystem","io","mkdir"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}