{"record":{"id":"d4dc37ecf11ad12e","repo":"apache/druid","slug":"unable-to-fetch-the-file-list-from-the-path-s","errorCode":null,"errorMessage":"Unable to fetch the file list from the path [%s]","messagePattern":"Unable to fetch the file list from the path \\[(.+?)\\]","errorType":"exception","errorClass":"org.apache.druid.java.util.common.ISE","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/storage/local/LocalFileStorageConnector.java","lineNumber":165,"sourceCode":"  public void deleteRecursively(String dirName) throws IOException\n  {\n    log.debug(\"Deleting directory at path: [%s]\", dirName);\n    FileUtils.deleteDirectory(fileWithBasePath(dirName));\n  }\n\n  @Override\n  public Iterator<String> listDir(String dirName)\n  {\n    File directory = fileWithBasePath(dirName);\n    if (!directory.exists()) {\n      throw new IAE(\"No directory exists on path [%s]\", dirName);\n    }\n    if (!directory.isDirectory()) {\n      throw new IAE(\"Cannot list contents of [%s] since it is not a directory\", dirName);\n    }\n    File[] files = directory.listFiles();\n    if (files == null) {\n      throw new ISE(\"Unable to fetch the file list from the path [%s]\", dirName);\n    }\n    return Arrays.stream(files).map(File::getName).iterator();\n  }\n\n  public File getBasePath()\n  {\n    return basePath;\n  }\n\n  private File fileWithBasePath(String path)\n  {\n    return new File(basePath, path);\n  }\n\n}\n","sourceCodeStart":147,"sourceCodeEnd":181,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/storage/local/LocalFileStorageConnector.java#L147-L181","documentation":"After confirming the path is a directory, listDir calls File.listFiles(); the JDK returns null (not an empty array) when an I/O error occurs, e.g. a permission problem or the directory disappearing concurrently. Druid converts that null into an IllegalStateException because it cannot distinguish 'empty' from 'failed'.","triggerScenarios":"listDir(dirName) where the directory exists and is a directory, but File.listFiles() returns null — typically because the process lacks read permission on the directory, or the directory was deleted between the isDirectory() check and listFiles().","commonSituations":"Druid running as a user without read access to the segment/task log directories; NFS or HDFS mounts dropping the directory mid-listing; concurrent cleanup job deleting intermediate task directories while a lookup runs.","solutions":["Check and fix filesystem permissions (read+execute on the directory) for the Druid process user","Re-run the operation; if a concurrent deleter is involved, serialize or skip deleted dirs","If persistent, inspect mount health (NFS/overlay) and ensure the directory is not being removed concurrently"],"exampleFix":"// before\nIterator<String> it = connector.listDir(\"logs\");\n// after\ntry {\n  Iterator<String> it = connector.listDir(\"logs\");\n} catch (IllegalStateException e) {\n  // check permissions on the logs directory for the druid user\n}","handlingStrategy":"try-catch","validationCode":"File dir = new File(basePath, dirName);\nif (!dir.canRead() || !dir.isDirectory()) {\n  throw new IllegalStateException(\"cannot read directory \" + dirName);\n}","typeGuard":null,"tryCatchPattern":"try { connector.listDir(dir); } catch (IllegalStateException e) { // treat as I/O failure: check perms, retry or fail }","preventionTips":["Ensure the Druid process user has read+execute on all listed directories","Avoid sharing directories with concurrent cleanup processes","Monitor filesystem mounts (NFS/overlay) for health"],"tags":["filesystem","io-error"],"backgroundTag":"permission-denied","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}