{"record":{"id":"b1cbde5dc7ada290","repo":"apache/hadoop","slug":"can-t-make-directory-for-path-s-since-it-is-a-f","errorCode":null,"errorMessage":"Can't make directory for path: %s, since it is a file.","messagePattern":"Can't make directory for path: (.+?), since it is a file\\.","errorType":"exception","errorClass":"FileAlreadyExistsException","httpStatus":null,"severity":"error","filePath":"hadoop-cloud-storage-project/hadoop-cos/src/main/java/org/apache/hadoop/fs/cosn/CosNFileSystem.java","lineNumber":545,"sourceCode":"   *                     creating the path.\n   */\n  public boolean mkDirRecursively(Path f, FsPermission permission)\n      throws IOException {\n    Path absolutePath = makeAbsolute(f);\n    List<Path> paths = new ArrayList<>();\n    do {\n      paths.add(absolutePath);\n      absolutePath = absolutePath.getParent();\n    } while (absolutePath != null);\n\n    for (Path path : paths) {\n      if (path.equals(new Path(CosNFileSystem.PATH_DELIMITER))) {\n        break;\n      }\n      try {\n        FileStatus fileStatus = getFileStatus(path);\n        if (fileStatus.isFile()) {\n          throw new FileAlreadyExistsException(\n              String.format(\"Can't make directory for path: %s, \"\n                  + \"since it is a file.\", f));\n        }\n        if (fileStatus.isDirectory()) {\n          break;\n        }\n      } catch (FileNotFoundException e) {\n        LOG.debug(\"Making dir: [{}] in COS\", f);\n\n        String folderPath = pathToKey(makeAbsolute(f));\n        if (!folderPath.endsWith(PATH_DELIMITER)) {\n          folderPath += PATH_DELIMITER;\n        }\n        store.storeEmptyFile(folderPath);\n      }\n    }\n    return true;\n  }","sourceCodeStart":527,"sourceCodeEnd":563,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-cloud-storage-project/hadoop-cos/src/main/java/org/apache/hadoop/fs/cosn/CosNFileSystem.java#L527-L563","documentation":"mkDirRecursively builds the missing ancestors of f bottom-up and, while checking each level, throws FileAlreadyExistsException if an existing entry there is a file. Note a reporting quirk: the message formats the ORIGINAL path f, not the ancestor that conflicted, so the message names the requested directory while the real conflict sits at some parent. Inspect parents when it fires.","triggerScenarios":"fs.mkdirs reaching mkDirRecursively after validatePath passed, then hitting an existing file at an intermediate level; a concurrent writer creating a file at an ancestor between validatePath and the recursive walk (time-of-check/time-of-use window).","commonSituations":"Concurrent jobs creating conflicting layouts under the same prefix; retries after partial failures that left files at intermediate paths.","solutions":["Walk every ancestor of the reported path, find the entry that isFile(), and remove or relocate it.","Serialize directory creation among concurrent writers or use a deterministic layout so collisions cannot occur.","Retry mkdirs after cleanup."],"exampleFix":"// before\nfs.mkdirs(new Path('/etl/dt=2026/zone=cn')); // message names /etl/dt=2026/zone=cn, but conflict is at an ancestor\n\n// after\nfor (Path a = new Path('/etl/dt=2026/zone=cn').getParent(); a != null; a = a.getParent()) {\n  if (fs.exists(a) && fs.getFileStatus(a).isFile()) { fs.delete(a, false); }\n}\nfs.mkdirs(new Path('/etl/dt=2026/zone=cn'));","handlingStrategy":"validation","validationCode":"for (Path anc = f.getParent(); anc != null && !anc.isRoot(); anc = anc.getParent()) {\n  if (fs.exists(anc) && fs.getFileStatus(anc).isFile()) {\n    throw new IllegalStateException('Ancestor is a file: ' + anc);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  fs.mkdirs(f);\n} catch (FileAlreadyExistsException e) {\n  // message names f, not the ancestor: walk parents to find the real file\n  for (Path a = f.getParent(); a != null; a = a.getParent()) {\n    if (fs.exists(a) && fs.getFileStatus(a).isFile()) { fs.delete(a, false); }\n  }\n  fs.mkdirs(f); // retry once\n}","preventionTips":["Serialize directory creation among concurrent writers on shared prefixes","Expect TOCTOU between validatePath and the recursive walk under concurrency","Retry mkdirs once after clearing conflicting ancestors"],"tags":["cosn","hadoop","mkdirs","race-condition","ancestor-is-file"],"backgroundTag":"parent-path-is-file","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}