{"record":{"id":"7219afd61b25cee3","repo":"apache/hadoop","slug":"can-t-open-path-because-it-is-a-directory","errorCode":null,"errorMessage":"Can't open {path} because it is a directory","messagePattern":"Can't open (.+?) because it is a directory","errorType":"exception","errorClass":"FileNotFoundException","httpStatus":null,"severity":"error","filePath":"hadoop-tools/hadoop-aliyun/src/main/java/org/apache/hadoop/fs/aliyun/oss/AliyunOSSFileSystem.java","lineNumber":609,"sourceCode":"        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(\n            boundedThreadPool, maxReadAheadPartNumber, true),\n        maxReadAheadPartNumber, store, pathToKey(path), fileStatus.getLen(),\n        statistics));\n  }\n\n  @Override\n  public boolean rename(Path srcPath, Path dstPath) throws IOException {\n    if (srcPath.isRoot()) {\n      // Cannot rename root of file system\n      if (LOG.isDebugEnabled()) {\n        LOG.debug(\"Cannot rename the root of a filesystem\");\n      }\n      return false;","sourceCodeStart":591,"sourceCodeEnd":627,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-tools/hadoop-aliyun/src/main/java/org/apache/hadoop/fs/aliyun/oss/AliyunOSSFileSystem.java#L591-L627","documentation":"Thrown by AliyunOSSFileSystem.open(): getFileStatus(path) succeeded but reported a directory, and OSS has no way to read a 'directory' as a byte stream (directories are just key prefixes, possibly marker objects). open() therefore fails with FileNotFoundException(\"Can't open \" + path + \" because it is a directory\").","triggerScenarios":"Calling fs.open(path) / fs.openFile(path) where path resolves to a directory marker or a prefix containing children; reading the output of a mapreduce job at the output directory instead of a specific part file; passing a partition directory to a reader expecting a file.","commonSituations":"Users opening the job output directory instead of part-00000; passing oss://bucket/dataset/date=2024-01-01 (a partition dir) to a tool that expects one file; marker objects left by other writers making a nonexistent-file path stat as directory.","solutions":["Open a concrete file: list the directory with fs.listStatus(dir) and open each file, or construct the exact part file path","Use a directory-aware reader (e.g., Spark/Hive reading the partition path) instead of FileSystem.open","If the path should be a file, check whether a write failed or the key was created as a marker by another tool, and rewrite it"],"exampleFix":"// before\nFSDataInputStream in = fs.open(new Path(\"oss://bucket/out\")); // out/ is a dir\n\n// after\nfor (FileStatus st : fs.listStatus(new Path(\"oss://bucket/out\"))) {\n  if (st.isFile()) { try (FSDataInputStream in = fs.open(st.getPath())) { /* read */ } }\n}","handlingStrategy":"type-guard","validationCode":"FileStatus st = fs.getFileStatus(path);\nif (st.isDirectory()) {\n  throw new IOException(\"open() target is a directory: \" + path);\n}","typeGuard":"private boolean isReadableFile(FileSystem fs, Path p) throws IOException {\n  FileStatus st = fs.getFileStatus(p);\n  return st.isFile();\n}","tryCatchPattern":"catch (FileNotFoundException e) { if (e.getMessage().contains(\"because it is a directory\")) { /* list and read children instead */ } else throw e; }","preventionTips":["Stat the path and require isFile() before open()","Point readers at concrete part files or use directory-aware engines (Spark/Hive) for partition paths"],"tags":["aliyun-oss","open","is-directory","hadoop-connector"],"backgroundTag":"read-path-is-directory","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}