{"record":{"id":"a8bbdb4ef27908c2","repo":"apache/hadoop","slug":"filesystem-does-not-support-non-recursivemkdir","errorCode":null,"errorMessage":"FileSystem does not support non-recursivemkdir","messagePattern":"FileSystem does not support non-recursivemkdir","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/DistributedFileSystem.java","lineNumber":1606,"sourceCode":"\n  private boolean mkdirsInternal(Path f, final FsPermission permission,\n      final boolean createParent) throws IOException {\n    statistics.incrementWriteOps(1);\n    storageStatistics.incrementOpCounter(OpType.MKDIRS);\n    Path absF = fixRelativePart(f);\n    return new FileSystemLinkResolver<Boolean>() {\n      @Override\n      public Boolean doCall(final Path p) throws IOException {\n        return dfs.mkdirs(getPathName(p), permission, createParent);\n      }\n\n      @Override\n      public Boolean next(final FileSystem fs, final Path p)\n          throws IOException {\n        // FileSystem doesn't have a non-recursive mkdir() method\n        // Best we can do is error out\n        if (!createParent) {\n          throw new IOException(\"FileSystem does not support non-recursive\"\n              + \"mkdir\");\n        }\n        return fs.mkdirs(p, permission);\n      }\n    }.resolve(this, absF);\n  }\n\n  @SuppressWarnings(\"deprecation\")\n  @Override\n  protected boolean primitiveMkdir(Path f, FsPermission absolutePermission)\n      throws IOException {\n    statistics.incrementWriteOps(1);\n    storageStatistics.incrementOpCounter(OpType.PRIMITIVE_MKDIR);\n    return dfs.primitiveMkdir(getPathName(f), absolutePermission);\n  }\n\n\n  @Override","sourceCodeStart":1588,"sourceCodeEnd":1624,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/DistributedFileSystem.java#L1588-L1624","documentation":"mkdirs(Path, FsPermission, createParent) resolves symlinks with FileSystemLinkResolver; when the final path component lands on another filesystem, next(fs, p) runs on that filesystem. The generic FileSystem API has no non-recursive mkdir, so when createParent is false the client cannot preserve the semantics and throws IOException rather than silently creating parents.","triggerScenarios":"Calling fs.mkdirs(path, perm, createParent=false) where path (after symlink resolution) crosses onto a different FileSystem, e.g. an HDFS symlink pointing to a local or object-store directory.","commonSituations":"Tooling that creates leaf directories atomically (createParent=false) over data layouts that mix HDFS with other schemes via symlinks; migrations where a mount table entry now resolves cross-scheme; unit environments using viewfs/local mounts.","solutions":["Call createParent=true (or plain fs.mkdirs(p, perm)) if creating parents on the target filesystem is acceptable.","Create the directory on the target filesystem directly: resolve the link target and open the right FileSystem instance.","Restructure so mkdirs never traverses a cross-filesystem symlink.","Ensure parent directories already exist on the target filesystem so the non-recursive semantics are trivially satisfied."],"exampleFix":"// before\nboolean ok = hdfs.mkdirs(linkPath, perm, /*createParent*/ false); // IOException cross-filesystem\n\n// after\nPath target = hdfs.getLinkTarget(linkPath);\nFileSystem targetFs = FileSystem.get(target.toUri(), conf);\nboolean ok = targetFs.mkdirs(target, perm, false);","handlingStrategy":"fallback","validationCode":"// Only needed when createParent=false and path may be a symlink:\nFileStatus st = fs.getFileLinkStatus(p);\nboolean crossFs = st.isSymlink()\n    && !fs.getUri().equals(FileSystem.get(st.getSymlink().toUri(), conf).getUri());\nif (crossFs && !createParent) { /* use fallback path */ }","typeGuard":null,"tryCatchPattern":"try {\n  ok = fs.mkdirs(p, perm, false);\n} catch (IOException e) {\n  if (e.getMessage().contains(\"non-recursive\")) {\n    ok = fs.mkdirs(p, perm, true); // or resolve target fs\n  } else throw e;\n}","preventionTips":["Know whether your paths can be cross-filesystem symlinks before choosing createParent=false.","Keep parent creation explicit (create parents first, then the leaf) instead of relying on recursive semantics.","Avoid symlinked roots for directory-creation logic."],"tags":["hdfs","mkdirs","symlink","cross-filesystem","filesystemlinkresolver","distributed-filesystem"],"backgroundTag":"symlink-cross-filesystem-unsupported","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}