{"record":{"id":"097779aee03d6337","repo":"apache/hadoop","slug":"can-t-make-directory-for-path-s-since-it-is-a-f-097779","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-huaweicloud/src/main/java/org/apache/hadoop/fs/obs/OBSCommonUtils.java","lineNumber":731,"sourceCode":"    FileStatus fileStatus;\n    try {\n      fileStatus = owner.getFileStatus(path);\n\n      if (fileStatus.isDirectory()) {\n        return true;\n      } else {\n        throw new FileAlreadyExistsException(\"Path is a file: \" + path);\n      }\n    } catch (FileNotFoundException e) {\n      Path fPart = path.getParent();\n      do {\n        try {\n          fileStatus = owner.getFileStatus(fPart);\n          if (fileStatus.isDirectory()) {\n            break;\n          }\n          if (fileStatus.isFile()) {\n            throw new FileAlreadyExistsException(\n                String.format(\"Can't make directory for path '%s'\"\n                    + \" since it is a file.\", fPart));\n          }\n        } catch (FileNotFoundException fnfe) {\n          LOG.debug(\"file {} not fount, but ignore.\", path);\n        }\n        fPart = fPart.getParent();\n      } while (fPart != null);\n\n      String key = pathToKey(owner, path);\n      if (owner.isFsBucket()) {\n        OBSPosixBucketUtils.fsCreateFolder(owner, key);\n      } else {\n        OBSObjectBucketUtils.createFakeDirectory(owner, key);\n      }\n      return true;\n    }\n  }","sourceCodeStart":713,"sourceCodeEnd":749,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-cloud-storage-project/hadoop-huaweicloud/src/main/java/org/apache/hadoop/fs/obs/OBSCommonUtils.java#L713-L749","documentation":"When innerMkdirs cannot find the requested directory, it walks UP the ancestor chain (fPart = path.getParent(); do/while to root) and stats each parent. If any ancestor exists as a FILE, it throws FileAlreadyExistsException(\"Can't make directory for path '<ancestor>' since it is a file.\") — you cannot create a directory underneath an object key. Note the reported path is the offending ANCESTOR (fPart), not the path you passed, which often confuses readers of the message.","triggerScenarios":"mkdirs('obs://b/a/b/c') when object 'obs://b/a' exists as a file: the walk hits a, sees isFile(), throws naming 'a'. Typical with key layouts where 'a' was written as a plain object and later code assumes it is a directory; flatten-then-hierarchical schema changes; upstream producers writing marker files at directory prefixes.","commonSituations":"Schema evolution adding partition levels under a formerly leaf key; different writers disagreeing whether a prefix is a file or dir; manual uploads of files named like directories; migration from another FS where such layout was legal.","solutions":["Identify the file named in the message, confirm it is disposable, then delete or rename it (fs.rename to a '_files/' prefix or delete).","Restructure the layout so every path component used as a directory is only ever a directory/prefix.","Add a layout lint at job start: for each mkdirs target, verify no ancestor exists as a file (cheap getFileStatus walk) and fail with an actionable message.","If the file must stay, move your data tree to a sibling prefix that has no file ancestors."],"exampleFix":"// before\nfs.mkdirs(new Path(\"obs://b/a/b/c\"));\n// throws: Can't make directory for path 'obs://b/a' since it is a file.\n\n// after\nPath a = new Path(\"obs://b/a\");\nif (fs.getFileStatus(a).isFile()) {\n  fs.rename(a, new Path(\"obs://b/_files/a\")); // relocate conflicting object\n}\nfs.mkdirs(new Path(\"obs://b/a/b/c\"));","handlingStrategy":"validation","validationCode":"static void ensureAncestorsAreDirs(FileSystem fs, Path p) throws IOException {\n  for (Path a = p.getParent(); a != null && !a.isRoot(); a = a.getParent()) {\n    if (fs.exists(a) && fs.getFileStatus(a).isFile()) {\n      throw new FileAlreadyExistsException(\"ancestor is a file: \" + a);\n    }\n  }\n  fs.mkdirs(p);\n}","typeGuard":null,"tryCatchPattern":"try {\n  fs.mkdirs(path);\n} catch (FileAlreadyExistsException e) {\n  if (String.valueOf(e.getMessage()).contains(\"since it is a file\")) {\n    // message names the offending ANCESTOR, not 'path'\n    Path offender = extractQuotedPath(e.getMessage());\n    throw new LayoutConflictException(\"file blocks directory tree at \" + offender, e);\n  }\n  throw e;\n}","preventionTips":["Never write a plain object at a key that other code uses as a directory prefix.","When adding partition depth to an existing layout, migrate the old leaf objects first.","Remember the message reports the ancestor path — parse it to find the blocker quickly."],"tags":["obs","huaweicloud","mkdirs","ancestors","file-already-exists"],"backgroundTag":"mkdir-file-conflict","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}