SonarSource/sonarqube · error

Cannot write Elasticsearch jvm options file

Error message

Cannot write Elasticsearch jvm options file

What it means

EsJvmOptions.writeToJvmOptionFile renders all Elasticsearch JVM options plus a warning header and writes them to the target file with Files.write in UTF-8. Any IOException is wrapped in an IllegalStateException because the generated jvm.options file is required for the Elasticsearch child process to start.

Source

Thrown at server/sonar-main/src/main/java/org/sonar/application/command/EsJvmOptions.java:134

    // log4j 2
    res.put("-Dlog4j.shutdownHookEnabled=", "false");
    res.put("-Dlog4j2.disable.jmx=", "true");
    res.put("-Dlog4j2.formatMsgNoLookups=", "true");
    /*
     * Due to internationalization enhancements in JDK 9 org.sonarqube.ws.tester.Elasticsearch need to set the provider to COMPAT otherwise
     * time/date
     * parsing will break in an incompatible way for some date patterns and locales.
     */
    res.put("-Djava.locale.providers=", "COMPAT");
  }

  public void writeToJvmOptionFile(File file) {
    String jvmOptions = getAll().stream().collect(Collectors.joining("\n"));
    String jvmOptionsContent = ELASTICSEARCH_JVM_OPTIONS_HEADER + jvmOptions;
    try {
      Files.write(file.toPath(), jvmOptionsContent.getBytes(StandardCharsets.UTF_8));
    } catch (IOException e) {
      throw new IllegalStateException("Cannot write Elasticsearch jvm options file", e);
    }
  }
}

View on GitHub (pinned to 184c821202)

Solutions

  1. Ensure the target directory for the jvm.options file exists and is writable by the SonarQube process user
  2. Free disk space on the partition holding the Elasticsearch files
  3. Fix filesystem permissions/ownership of the sonarqube install and temp directories (chown to the service user)
  4. Check the wrapped IOException cause in the stack trace to identify the exact filesystem problem

Example fix

// before
$SONAR_HOME/elasticsearch owned by root, service runs as sonarqube
// after
chown -R sonarqube:sonarqube $SONAR_HOME/elasticsearch
chmod -R u+w $SONAR_HOME/elasticsearch
Defensive patterns

Strategy: try-catch

Validate before calling

File dir = file.getParentFile();
if (!dir.isDirectory() || !dir.canWrite() || dir.getUsableSpace() < 5 * 1024 * 1024) {
  throw new IllegalStateException("ES jvm.options target dir not writable/full: " + dir);
}

Type guard

boolean canWriteFile(File f) {
  File p = f.getParentFile();
  return f.canWrite() || (!f.exists() && p != null && p.isDirectory() && p.canWrite());
}

Try / catch

try {
  esJvmOptions.writeToJvmOptionFile(file);
} catch (IllegalStateException e) {
  if (e.getMessage().equals("Cannot write Elasticsearch jvm options file")) {
    log.error("Check ES dir permissions and disk space", e.getCause());
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling writeToJvmOptionFile when the destination directory does not exist, the path is not writable by the process user, or the disk is full while writing the Elasticsearch jvm.options file.

Common situations: Elasticsearch data/temp directories on read-only mounts, permission-restricted install directories after package upgrades, exhausted disk space on the ES node, or the target file locked by another process on Windows.

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/32eb9d9e7bddfe90. Report an issue: GitHub.