SonarSource/sonarqube · error

Could not delete Elasticsearch temporary conf directory

Error message

Could not delete Elasticsearch temporary conf directory

What it means

Before writing new Elasticsearch config files, pruneElasticsearchConfDirectory deletes any existing temporary conf directory using FileUtils2.deleteDirectory. If that deletion throws IOException (locked files, permissions, I/O errors), it is wrapped in this IllegalStateException because stale ES configuration would corrupt the next launch.

Source

Thrown at server/sonar-main/src/main/java/org/sonar/application/ProcessLauncherImpl.java:158

  private void writeConfFiles(EsInstallation esInstallation) {
    File confDir = esInstallation.getConfDirectory();

    pruneElasticsearchConfDirectory(confDir);
    createElasticsearchConfDirectory(confDir);
    setupElasticsearchSecurity(esInstallation);

    esInstallation.getEsYmlSettings().writeToYmlSettingsFile(esInstallation.getElasticsearchYml());
    esInstallation.getEsJvmOptions().writeToJvmOptionFile(esInstallation.getJvmOptions());
    storeElasticsearchLog4j2Properties(esInstallation);
  }

  private static void pruneElasticsearchConfDirectory(File confDir) {
    try {
      if (confDir.exists()) {
        FileUtils2.deleteDirectory(confDir);
      }
    } catch (IOException e) {
      throw new IllegalStateException("Could not delete Elasticsearch temporary conf directory", e);
    }
  }

  private static void createElasticsearchConfDirectory(File confDir) {
    if (!confDir.mkdirs()) {
      String error = format("Failed to create temporary configuration directory [%s]", confDir.getAbsolutePath());
      LOG.error(error);
      throw new IllegalStateException(error);
    }
  }

  private void setupElasticsearchSecurity(EsInstallation esInstallation) {
    if (esInstallation.isSecurityEnabled()) {
      EsKeyStoreCli keyStoreCli = EsKeyStoreCli.getInstance(esInstallation);

      setupElasticsearchAuthentication(esInstallation, keyStoreCli);
      setupElasticsearchHttpEncryption(esInstallation, keyStoreCli);

View on GitHub (pinned to 184c821202)

Solutions

  1. Ensure no old SonarQube/Elasticsearch process is still running, then delete <temp>/conf manually.
  2. Fix ownership/permissions on the sonar.path.temp directory for the sonarqube user.
  3. Clear the temp directory entirely while the server is stopped.
  4. On Windows, exclude the temp path from antivirus/indexing that may lock files.

Example fix

$ sudo systemctl stop sonarqube
$ ps aux | grep -i elasticsearch   # kill stragglers
$ rm -rf /opt/sonarqube/temp/conf
$ sudo systemctl start sonarqube
Defensive patterns

Strategy: retry

Validate before calling

File conf = new File(tempDir, "conf");
if (conf.exists() && !isDeletable(conf)) {
    throw new IllegalStateException("Temp ES conf dir locked/undeletable: " + conf);
}

Try / catch

try { launcher.launch(...); } catch (IllegalStateException e) {
    if (e.getMessage().contains("Could not delete Elasticsearch")) { cleanTempDir(); retry(); }
}

Prevention

When it happens

Trigger: writeConfFiles() -> pruneElasticsearchConfDirectory() when confDir.exists() but FileUtils2.deleteDirectory(confDir) throws IOException — e.g. a file in the temp ES conf dir is held open or is read-only.

Common situations: Previous SonarQube process still running and holding files in the temp dir; read-only or permission-denied temp directory; antivirus/indexers locking files on Windows; leftover root-owned files after running as a different user.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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