{"record":{"id":"7fd51e648d03f5b5","repo":"apache/hadoop","slug":"can-t-make-directory-for-path-s-it-is-a-file-7fd51e","errorCode":null,"errorMessage":"Can't make directory for path '%s', it is a file.","messagePattern":"Can't make directory for path '(.+?)', it is a file\\.","errorType":"exception","errorClass":"FileAlreadyExistsException","httpStatus":null,"severity":"error","filePath":"hadoop-tools/hadoop-aliyun/src/main/java/org/apache/hadoop/fs/aliyun/oss/AliyunOSSFileSystem.java","lineNumber":596,"sourceCode":"    }\n  }\n\n  /**\n   * Check whether the path is a valid path.\n   *\n   * @param path the path to be checked.\n   * @throws IOException\n   */\n  private void validatePath(Path path) throws IOException {\n    Path fPart = path.getParent();\n    do {\n      try {\n        FileStatus fileStatus = getFileStatus(fPart);\n        if (fileStatus.isDirectory()) {\n          // If path exists and a directory, exit\n          break;\n        } else {\n          throw new FileAlreadyExistsException(String.format(\n              \"Can't make directory for path '%s', it is a file.\", fPart));\n        }\n      } catch (FileNotFoundException fnfe) {\n      }\n      fPart = fPart.getParent();\n    } while (fPart != null);\n  }\n\n  @Override\n  public FSDataInputStream open(Path path, int bufferSize) throws IOException {\n    final FileStatus fileStatus = getFileStatus(path);\n    if (fileStatus.isDirectory()) {\n      throw new FileNotFoundException(\"Can't open \" + path +\n          \" because it is a directory\");\n    }\n\n    return new FSDataInputStream(new AliyunOSSInputStream(getConf(),\n        new SemaphoredDelegatingExecutor(","sourceCodeStart":578,"sourceCodeEnd":614,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-tools/hadoop-aliyun/src/main/java/org/apache/hadoop/fs/aliyun/oss/AliyunOSSFileSystem.java#L578-L614","documentation":"Thrown by AliyunOSSFileSystem.validatePath(), called from mkdirs after the target itself was not found. It walks every ancestor of the path; if any ancestor exists but is a file (not a directory), building the directory chain is impossible and it throws FileAlreadyExistsException(\"Can't make directory for path '%s', it is a file.\") naming that ancestor.","triggerScenarios":"Calling fs.mkdirs(deepPath) where an intermediate key exists as a file object — e.g., mkdirs(oss://bucket/a/b/c) while 'a' or 'a/b' is stored as a plain object; typically surfaced inside OutputCommitter/OutputFormat directory setup.","commonSituations":"Data layout evolution where a former leaf file became an interior path; keys written by non-Hadoop tools at conflicting prefixes; partial writes from a failed job leaving a file where a directory tree is expected.","solutions":["Identify the offending ancestor from the message and delete or rename that file object","Rework the path scheme so file names never double as directory prefixes","After cleanup, re-run the job; mkdirs then creates the directory markers without conflict"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"for (Path a = path.getParent(); a != null; a = a.getParent()) {\n  if (fs.exists(a) && fs.getFileStatus(a).isFile()) {\n    throw new IOException(\"Ancestor is a file: \" + a);\n  }\n}\nfs.mkdirs(path);","typeGuard":null,"tryCatchPattern":"catch (FileAlreadyExistsException e) { /* message names the offending ancestor; delete/rename it then retry mkdirs */ throw e; }","preventionTips":["Pre-validate the ancestor chain of deep output paths once at job setup","Avoid layouts where former leaf files become interior prefixes"],"tags":["aliyun-oss","mkdir","ancestor-conflict","hadoop-connector"],"backgroundTag":"mkdir-ancestor-is-file","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}