{"record":{"id":"966ebde3cfc20d5c","repo":"apache/hadoop","slug":"directory-is-not-executable-dir","errorCode":null,"errorMessage":"Directory is not executable: ${dir}","messagePattern":"Directory is not executable: (.+?)","errorType":"exception","errorClass":"DiskErrorException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/DiskChecker.java","lineNumber":171,"sourceCode":"  private static void checkAccessByFileMethods(File dir)\n      throws DiskErrorException {\n    if (!dir.isDirectory()) {\n      throw new DiskErrorException(\"Not a directory: \"\n          + dir.toString());\n    }\n\n    if (!FileUtil.canRead(dir)) {\n      throw new DiskErrorException(\"Directory is not readable: \"\n                                   + dir.toString());\n    }\n\n    if (!FileUtil.canWrite(dir)) {\n      throw new DiskErrorException(\"Directory is not writable: \"\n                                   + dir.toString());\n    }\n\n    if (!FileUtil.canExecute(dir)) {\n      throw new DiskErrorException(\"Directory is not executable: \"\n                                   + dir.toString());\n    }\n  }\n\n  /**\n   * The semantics of mkdirsWithExistsCheck method is different from the mkdirs\n   * method provided in the Sun's java.io.File class in the following way:\n   * While creating the non-existent parent directories, this method checks for\n   * the existence of those directories if the mkdir fails at any point (since\n   * that directory might have just been created by some other process).\n   * If both mkdir() and the exists() check fails for any seemingly\n   * non-existent directory, then we signal an error; Sun's mkdir would signal\n   * an error (return false) if a directory it is attempting to create already\n   * exists or the mkdir fails.\n   * @param dir\n   * @return true on success, false on failure\n   */\n  private static boolean mkdirsWithExistsCheck(File dir) {","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/DiskChecker.java#L153-L189","documentation":"checkAccessByFileMethods rejects a storage directory whose FileUtil.canExecute(dir) returns false, throwing DiskErrorException('Directory is not executable: <dir>'). For directories the execute bit is traverse permission — without it the daemon cannot stat or descend into paths under the directory, so it is treated as bad.","triggerScenarios":"Directory mode lacks the execute/traverse bit (e.g. 644); overly restrictive umask when the directory was auto-created; hardening scripts applying file modes to directories.","commonSituations":"chmod 644 applied recursively to a tree including directories; dirs created under umask 0777-style policies; containers where base images ship non-traversable dirs.","solutions":["Add the traverse bit: chmod u+x <dir> (or chmod 755) as appropriate","Fix recursive mode changes: directories need x (find <root> -type d -exec chmod 755 {} +)","Verify as the daemon user: sudo -u yarn ls <dir>/subdir","Review the umask under which the daemon creates storage dirs"],"exampleFix":"# before: a recursive chmod stripped the traverse bit\nchmod -R 644 /data/nm-local\n# after: restore x on directories only\nfind /data/nm-local -type d -exec chmod 755 {} +","handlingStrategy":"validation","validationCode":"import java.nio.file.*;\nfor (String dir : configuredDirs) {\n  Path p = Paths.get(dir);\n  if (!Files.isExecutable(p)) {\n    throw new IllegalStateException(\"directory lacks traverse (x) permission: \" + dir);\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never chmod -R a mode designed for files over trees containing directories","Restore directory bits with: find <root> -type d -exec chmod 755 {} +","Include the x-bit check in pre-start health scripts run as the daemon user"],"tags":["disk","permissions","filesystem","diskchecker","traverse"],"backgroundTag":"permission-denied","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}