SonarSource/sonarqube · critical

Fail to launch process [%s]

Error message

Fail to launch process [%s]

What it means

launchJava builds a ProcessBuilder from the given JavaCommand and starts the child JVM (web, CE, or Elasticsearch). Any exception during command creation or process start (missing java binary, invalid JVM options, OS exec failure) is wrapped in this IllegalStateException naming the process.

Source

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

    }
  }

  private static void storeElasticsearchLog4j2Properties(EsInstallation esInstallation) {
    try (FileOutputStream fileOutputStream = new FileOutputStream(esInstallation.getLog4j2PropertiesLocation())) {
      esInstallation.getLog4j2Properties().store(fileOutputStream, "log4j2 properties file for ES bundled in SonarQube");
    } catch (IOException e) {
      throw new IllegalStateException("Failed to write ES configuration files", e);
    }
  }

  private <T extends JvmOptions> Process launchJava(JavaCommand<T> javaCommand) {
    ProcessId processId = javaCommand.getProcessId();
    try {
      ProcessBuilder processBuilder = create(javaCommand);
      logLaunchedCommand(javaCommand, processBuilder);
      return processBuilder.start();
    } catch (Exception e) {
      throw new IllegalStateException(format("Fail to launch process [%s]", processId.getHumanReadableName()), e);
    }
  }

  private static <T extends AbstractCommand> void logLaunchedCommand(AbstractCommand<T> command, ProcessBuilder processBuilder) {
    LOG.atInfo()
      .addArgument(command::getProcessId)
      .addArgument(() -> command.getWorkDir().getAbsolutePath())
      .addArgument(() -> String.join(" ", processBuilder.command()))
      .log("Launch process[{}] from [{}]: {}");
  }

  private <T extends JvmOptions> ProcessBuilder create(JavaCommand<T> javaCommand) {
    List<String> commands = new ArrayList<>();
    commands.add(buildJavaPath());
    commands.addAll(javaCommand.getJvmOptions().getAll());
    commands.addAll(buildClasspath(javaCommand));
    commands.add(javaCommand.getClassName());
    commands.addAll(javaCommand.getParameters());

View on GitHub (pinned to 184c821202)

Solutions

  1. Inspect the 'Caused by' in logs/sonar.log for the root cause of the exec failure.
  2. Verify java (matching the required version) is on PATH or set JAVA_HOME correctly for the service user.
  3. Check sonar.web.javaOpts / sonar.ce.javaOpts / sonar.search.javaOpts for invalid arguments.
  4. Confirm the sonarqube user has execute permission on the JVM binary.

Example fix

// before
JAVA_HOME=/usr/lib/jvm/jdk-8  # unsupported/missing
// after
JAVA_HOME=/usr/lib/jvm/jdk-17  # supported JDK, on PATH for service user
Defensive patterns

Strategy: validation

Validate before calling

String javaHome = System.getenv("JAVA_HOME");
Path java = (javaHome != null ? Paths.get(javaHome, "bin", "java") : Paths.get("java"));
if (!Files.isExecutable(java)) {
    throw new IllegalStateException("Java executable not found/executable: " + java);
}

Try / catch

try { launcher.launch(command, false); } catch (IllegalStateException e) { log.severe("Process launch failed: " + e.getMessage() + ", cause=" + e.getCause()); }

Prevention

When it happens

Trigger: launch() -> launchJava() where create(javaCommand) or processBuilder.start() throws — typically the java executable cannot be found/executed, or an invalid JVM option/command line is assembled.

Common situations: JAVA_HOME pointing to a missing or non-executable JDK; a Java version incompatible with SonarQube; malformed memory settings (e.g. bad -Xmx values from sonar.web.javaOpts) causing immediate exec failure; PATH issues when running under a service manager.

Related errors


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