apache/druid · error · java.io.FileNotFoundException

Unable to find file for reading

Error message

Unable to find file %s for reading

What it means

LocalFileStorageConnector.readRange throws FileNotFoundException when the requested relative path does not exist under the connector's base path. It means a read of a byte range was requested for a file absent from local storage.

Solutions

  1. Confirm the exact relative path exists under the base path (ls); fix typos/case mismatches.
  2. Re-fetch or re-download the segment/file (trigger re-load or re-run export) since it may have been cleaned up.
  3. Check retention/cleanup jobs that may have deleted the file concurrently.
  4. Validate file existence before issuing range reads and handle FileNotFoundException explicitly in callers.

Example fix

// before
InputStream in = connector.readRange("export/2024/result.csv", 0, 1024); // file deleted
// after
File f = new File(basePath, "export/2024/result.csv");
if (!f.isFile()) {
  throw new FileNotFoundException("regenerate export: missing " + f);
}
InputStream in = connector.readRange("export/2024/result.csv", 0, 1024);
Defensive patterns

Strategy: try-catch

Validate before calling

if (!new File(basePath, path).isFile()) throw new FileNotFoundException(path);

Type guard

boolean exists(StorageConnector c, String p) { try { return c.pathExists(p); } catch (IOException e) { return false; } }

Try / catch

try { in = connector.readRange(path, from, size); } catch (FileNotFoundException e) { log.warn(e, "file missing: %s", path); in = regenerateAndReopen(path); }

Prevention

When it happens

Trigger: readRange(path, from, size) where pathExists(path) is false: file deleted (e.g. by cleanup/kill tasks), wrong relative path, segment not yet downloaded to local cache, typo or case-mismatch on the path.

Common situations: Segment files cleaned up while a task still needs them; querying an export file that finished/was removed; path casing differences on case-sensitive filesystems; load rule dropped the segment from the historical's cache.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

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

  }

  @Override
  public boolean pathExists(String path)
  {
    return fileWithBasePath(path).exists();
  }

  @Override
  public InputStream read(String path) throws IOException
  {
    return Files.newInputStream(fileWithBasePath(path).toPath());
  }

  @Override
  public InputStream readRange(String path, long from, long size) throws IOException
  {
    if (!pathExists(path)) {
      throw new FileNotFoundException("Unable to find file " + fileWithBasePath(path).toPath() + " for reading");
    }
    long length = fileWithBasePath(path).length();
    if (from < 0 || size < 0 || (from + size) > length) {
      throw new IAE(
          "Invalid arguments for reading %s. from = %d, readSize = %d, fileSize = %d",
          fileWithBasePath(path).toPath(),
          from,
          size,
          length
      );
    }
    FileChannel fileChannel = FileChannel.open(fileWithBasePath(path).toPath(), StandardOpenOption.READ);
    return new BoundedInputStream(Channels.newInputStream(fileChannel.position(from)), size);
  }

  /**
   * Writes the file present with the materialized location as basePath + path.
   * In case the parent directory does not exist, we create the parent dir recursively.

View on GitHub (pinned to 9b90983fd2)