SonarSource/sonarqube · error · IllegalStateException

Can get file ${filename}

Error message

Can get file ${filename}

What it means

BatchIndex.getFile resolves a scanner-provided filename inside the batch working directory and returns it as a File. If the resolved path escapes batchDir (path traversal check via FilenameUtils.directoryContains) or does not exist, a NotFoundException is thrown; if resolving canonical paths or checking existence throws an IOException, it is wrapped in this IllegalStateException. It guards the batch download endpoint against bad or malicious filenames.

Source

Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/batch/BatchIndex.java:94

  @Override
  public void stop() {
    // Nothing to do
  }

  String getIndex() {
    return index;
  }

  File getFile(String filename) {
    try {
      File input = new File(batchDir, filename);
      if (!FilenameUtils.directoryContains(batchDir.getCanonicalPath(), input.getCanonicalPath()) || !input.exists()) {
        throw new NotFoundException("Bad filename: " + filename);
      }
      return input;
    } catch (IOException e) {
      throw new IllegalStateException("Can get file " + filename, e);
    }
  }
}

View on GitHub (pinned to 184c821202)

Solutions

  1. Re-run the scanner so it re-requests a freshly generated batch manifest
  2. Check the file still exists in the batch directory and that batchDir/files were not pruned
  3. Verify the filename in the request has no path separators or '..' segments
  4. Ensure the batch directory is not a symlink and no canonicalization mismatch (different mounts, case-insensitive FS)

Example fix

// before
File input = new File(batchDir, filename);
// after
File input = new File(batchDir, new File(filename).getName()); // strip path components before resolution
Defensive patterns

Strategy: validation

Validate before calling

if (filename.contains("/") || filename.contains("..")) throw new IllegalArgumentException("bad filename");
// also ensure the file was listed in the current batch manifest before requesting it

Try / catch

try { File f = batchIndex.getFile(filename); } catch (NotFoundException e) { reRequestBatch(); }

Prevention

When it happens

Trigger: GET of a batch/file resource where the filename contains path separators or '..' so canonicalization fails mid-check, or the underlying file is deleted/renamed between the exists() check and canonical path computation causing an IOException.

Common situations: Scanner caching a file URL and the server's batch directory being cleaned up (temp cleanup, restart) before download; corrupted or hand-crafted scanner requests with traversal-style filenames; symlinked batch directories breaking canonical-path containment.

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 SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/d36ac640a7a6082d. Report an issue: GitHub.