SonarSource/sonarqube · error · NotFoundException

Scanner directory not found

Error message

Scanner directory not found: %s

What it means

Thrown by ScannerEngineHandlerImpl.getScannerEngine() when the <homeDir>/lib/scanner directory does not exist, meaning the server distribution is incomplete or was not fully deployed. Callers (the scanner engine download endpoint) surface this as a 404.

Solutions

  1. Restore lib/scanner from a complete SonarQube distribution download
  2. Verify the process is using the correct home directory (fs.getHomeDir) pointing to the full installation
  3. Reinstall SonarQube properly instead of copying over an existing installation
  4. Check that deployment/backup tooling does not exclude lib/scanner

Example fix

// before
File scannerDir = new File(fs.getHomeDir(), "lib/scanner");
// after
File scannerDir = new File(fs.getHomeDir(), "lib/scanner");
if (!scannerDir.exists()) {
  // reinstall distribution or restore from the official zip so lib/scanner exists
  throw new NotFoundException(format("Scanner directory not found: %s", scannerDir.getAbsolutePath()));
}
Defensive patterns

Strategy: try-catch

Validate before calling

#!/bin/bash
# preflight: verify the scanner lib directory exists
if [ ! -d "$SONAR_HOME/lib/scanner" ]; then
  echo "lib/scanner missing - reinstall the SonarQube distribution" >&2
  exit 1
fi

Type guard

function isDistributionComplete(sonarHome) {
  return fs.existsSync(path.join(sonarHome, 'lib', 'scanner'));
}

Try / catch

try {
  const engine = await downloadScannerEngine();
} catch (err) {
  if (err.status === 404 && /Scanner directory not found/.test(err.message)) {
    // restore lib/scanner from the official distribution before retrying
  } else { throw err; }
}

Prevention

When it happens

Trigger: GET api/v2/analysis/engine when the installation directory lacks lib/scanner; upgrading/partially copying a distribution; deleting lib/scanner manually.

Common situations: Manual SonarQube deployments where only some files were copied, container images built with a slimmed/incorrect set of files, hardened setups that stripped lib/scanner, wrong SONAR_HOME pointing at an empty directory.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/41becd744868f9fb. Report an issue: GitHub.

Appendix: source

Thrown at server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/analysis/service/ScannerEngineHandlerImpl.java:49

import static org.apache.commons.io.FileUtils.listFiles;
import static org.apache.commons.io.filefilter.FileFilterUtils.directoryFileFilter;
import static org.apache.commons.io.filefilter.HiddenFileFilter.VISIBLE;

public class ScannerEngineHandlerImpl implements ScannerEngineHandler {

  private final ServerFileSystem fs;

  private ScannerEngineMetadata scannerEngineMetadata;

  public ScannerEngineHandlerImpl(ServerFileSystem fs) {
    this.fs = fs;
  }

  @Override
  public File getScannerEngine() {
    File scannerDir = new File(fs.getHomeDir(), "lib/scanner");
    if (!scannerDir.exists()) {
      throw new NotFoundException(format("Scanner directory not found: %s", scannerDir.getAbsolutePath()));
    }
    return listFiles(scannerDir, VISIBLE, directoryFileFilter())
      .stream()
      .filter(file -> file.getName().endsWith(".jar"))
      .findFirst()
      .orElseThrow(() -> new NotFoundException(format("Scanner JAR not found in directory: %s", scannerDir.getAbsolutePath())));
  }

  private static String getSha256(File file) {
    try (FileInputStream fileInputStream = new FileInputStream(file)) {
      return sha256Hex(fileInputStream);
    } catch (IOException exception) {
      throw new UncheckedIOException(new IOException("Unable to compute SHA-256 checksum of the Scanner Engine", exception));
    }
  }

  @Override
  public ScannerEngineMetadata getScannerEngineMetadata() {

View on GitHub (pinned to 184c821202)