elastic/elasticsearch · critical · RuntimeException

Elasticsearch died while starting up, exit code: ${exitCode}

Error message

Elasticsearch died while starting up, exit code: ${exitCode}

What it means

Thrown by WindowsServiceDaemon when the spawned Elasticsearch JVM process exits before the ErrorPumpThread signals that the server is ready. The error includes the JVM's exit code, which is the single most useful diagnostic. This is a wrapper around a process-level death: the JVM started, ran briefly, and returned non-zero, so the cause is almost always visible earlier in the ErrorPump output or in the Elasticsearch log file.

Source

Thrown at distribution/tools/windows-service-cli/src/main/java/org/elasticsearch/windows/service/WindowsServiceDaemon.java:106

        pb.environment().clear();
        pb.environment().putAll(environment);
        pb.directory(new File(workingDir.toString()));
        pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);

        Process jvmProcess = null;
        ErrorPumpThread errorPump;
        boolean success = false;

        try {
            jvmProcess = pb.start();
            errorPump = new ErrorPumpThread(jvmProcess.getErrorStream(), System.err);
            errorPump.start();
            sendServerArgs(serverArgsBytes, jvmProcess.getOutputStream());

            boolean serverOk = errorPump.waitUntilReady();
            if (serverOk == false) {
                int exitCode = jvmProcess.waitFor();
                throw new RuntimeException("Elasticsearch died while starting up, exit code: " + exitCode);
            }
            success = true;
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        } finally {
            if (success == false && jvmProcess != null && jvmProcess.isAlive()) {
                jvmProcess.destroyForcibly();
            }
        }

        return new ServerProcess(jvmProcess, errorPump);
    }

    private static String getJavaCommand(ProcessInfo processInfo) {
        Path javaHome = Path.of(processInfo.sysprops().get("java.home"));
        return javaHome.resolve("bin").resolve("java.exe").toString();

View on GitHub (pinned to db6a809a66)

Solutions

  1. Read the ErrorPump output printed just before this exception — it usually contains the real cause.
  2. Open the Elasticsearch log file under logs/ for the full stack trace.
  3. Cross-reference the exit code: 1 = generic JVM error, 137 = OOM-kill, 134 = JVM crash (hs_err_pid file).
  4. Validate jvm.options and elasticsearch.yml with a config-only boot (`-E` dry run) before starting as a service.
  5. For hs_err crashes, inspect the hs_err_pid*.log file in the working directory.

Example fix

REM before: service starts, JVM dies with exit code 1
REM inspect logs:
type %ES_HOME%\logs\elasticsearch.log
REM after: fix the offending setting (e.g. remove unsupported -XX flag)
bin\elasticsearch-service.bat start
Defensive patterns

Strategy: try-catch

Validate before calling

// Before running as a service, validate config with a foreground run:
// bin/elasticsearch -E ...  (exits non-zero if config is bad)
// Capture exit code; only register as a service if foreground run succeeds.

Type guard

static boolean jvmLooksHealthy(Path logsDir) throws IOException {
    // Returns true if the latest log line indicates successful startup markers
    return Files.lines(logsDir.resolve("elasticsearch.log"))
        .anyMatch(l -> l.contains("started") || l.contains("bound_addresses"));
}

Try / catch

try {
    WindowsServiceDaemon.main(args);
} catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().contains("died while starting up")) {
        // read logs/elasticsearch.log and the ErrorPump output to find root cause
        log.error("Elasticsearch failed to start as a service; inspect logs/", e);
    } else throw e;
}

Prevention

When it happens

Trigger: JVM exits due to fatal startup error: invalid jvm.options, OOM during bootstrap, missing required setting, entitlement violation, port already in use, or classpath corruption. The ErrorPump's `waitUntilReady` returns false because it never observed the readiness marker.

Common situations: First run after an upgrade with incompatible jvm.options. Locked memory (bootstrap checks) failing on a non-systemd Windows host. bind() collision on http/transport ports. Insufficient heap.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/5ad15a74cc476441. Report an issue: GitHub.