apache/druid · error · org.apache.druid.java.util.common.IAE

No directory exists on path

Error message

No directory exists on path [%s]

What it means

LocalFileStorageConnector.listDir throws IAE when the requested directory does not exist under the base path, before attempting to list contents. A separate IAE follows if the path exists but is not a directory.

Solutions

  1. Verify the directory exists (ls under the connector base path) and correct the dir name/casing.
  2. Create the directory if your workflow expects it to exist (Files.createDirectories) before listing.
  3. Check for races with cleanup/delete jobs and coordinate or retry.
  4. Confirm the connector's base path configuration matches where files were actually written.

Example fix

// before
Iterator<String> it = connector.listDir("exports/2024-06"); // may not exist
// after
File dir = new File(basePath, "exports/2024-06");
if (!dir.isDirectory()) {
  return Collections.emptyIterator();
}
Iterator<String> it = connector.listDir("exports/2024-06");
Defensive patterns

Strategy: validation

Validate before calling

File d = new File(basePath, dirName);
if (!d.isDirectory()) { Files.createDirectories(d.toPath()); }

Type guard

boolean isDir(String p) { File d = new File(basePath, p); return d.exists() && d.isDirectory(); }

Try / catch

try { it = connector.listDir(dirName); } catch (IllegalArgumentException e) { log.warn(e, "missing dir %s", dirName); it = Collections.emptyIterator(); }

Prevention

When it happens

Trigger: listDir(dirName) where fileWithBasePath(dirName).exists() is false: never-created export dir, directory already deleted by cleanup, wrong relative dir name, or case mismatch on case-sensitive filesystems.

Common situations: Listing an export directory before the export task created it; cleanup jobs removing dirs while being listed; misconfigured base dir so relative paths resolve differently than expected.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/0bdfcdf597e4195b. Report an issue: GitHub.

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/storage/local/LocalFileStorageConnector.java:158

  /**
   * Deletes the files and sub dirs present at the basePath + dirName. Also removes the dirName
   *
   * @param dirName path
   * @throws IOException thrown in case of errors.
   */
  @Override
  public void deleteRecursively(String dirName) throws IOException
  {
    log.debug("Deleting directory at path: [%s]", dirName);
    FileUtils.deleteDirectory(fileWithBasePath(dirName));
  }

  @Override
  public Iterator<String> listDir(String dirName)
  {
    File directory = fileWithBasePath(dirName);
    if (!directory.exists()) {
      throw new IAE("No directory exists on path [%s]", dirName);
    }
    if (!directory.isDirectory()) {
      throw new IAE("Cannot list contents of [%s] since it is not a directory", dirName);
    }
    File[] files = directory.listFiles();
    if (files == null) {
      throw new ISE("Unable to fetch the file list from the path [%s]", dirName);
    }
    return Arrays.stream(files).map(File::getName).iterator();
  }

  public File getBasePath()
  {
    return basePath;
  }

  private File fileWithBasePath(String path)
  {

View on GitHub (pinned to 9b90983fd2)