elastic/elasticsearch · error · UserException

CONFIG

CONFIG

Error message

Invalid java installation (no jvm.dll found in %s\jre\bin\server\ or %s\bin\server\"). Exiting...

What it means

Thrown by WindowsServiceInstallCommand.preExecute when ES_JAVA_HOME does not contain a server JVM shared library (jvm.dll) in either `<javaHome>\jre\bin\server\` (legacy JRE layout) or `<javaHome>\bin\server\` (modern JDK layout). Procrun needs jvm.dll to host the JVM inside the service process, so its absence means the install cannot proceed. Exit code CONFIG marks this as an environment problem rather than a usage problem.

Source

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

    private static String getJvmOptions(Map<String, String> sysprops) {
        List<String> jvmOptions = new ArrayList<>();
        jvmOptions.add("-XX:+UseSerialGC");
        // passthrough these properties
        for (var prop : List.of("es.path.home", "es.path.conf", "es.distribution.type")) {
            jvmOptions.add("-D%s=%s".formatted(prop, quote(sysprops.get(prop))));
        }
        return String.join(";", jvmOptions);
    }

    @Override
    protected void preExecute(Terminal terminal, ProcessInfo pinfo, String serviceId) throws UserException {
        Path javaHome = getJavaHome(pinfo.sysprops());
        terminal.println(String.format(java.util.Locale.ROOT, "Installing service : %s", serviceId));
        terminal.println(String.format(java.util.Locale.ROOT, "Using ES_JAVA_HOME : %s", javaHome.toString()));

        Path javaDll = getJvmDll(javaHome);
        if (Files.exists(javaDll) == false) {
            throw new UserException(
                ExitCodes.CONFIG,
                "Invalid java installation (no jvm.dll found in %s\\jre\\bin\\server\\ or %s\\bin\\server\"). Exiting...".formatted(
                    javaHome.toString(),
                    javaHome.toString()
                )
            );
        }

        // validate username and password come together
        boolean hasUsername = pinfo.envVars().containsKey("SERVICE_USERNAME");
        if (pinfo.envVars().containsKey("SERVICE_PASSWORD") != hasUsername) {
            throw new UserException(
                ExitCodes.CONFIG,
                "Both service username and password must be set, only got " + (hasUsername ? "SERVICE_USERNAME" : "SERVICE_PASSWORD")
            );
        }
    }

View on GitHub (pinned to db6a809a66)

Solutions

  1. Verify the dll exists: `dir "%ES_JAVA_HOME%\bin\server\jvm.dll"`.
  2. Install a full JDK (e.g. Eclipse Temurin JDK) that ships the server JVM.
  3. Set ES_JAVA_HOME to the JDK root (the directory containing bin/, lib/, conf/).
  4. If you must use a legacy JRE layout, ensure `<javaHome>\jre\bin\server\jvm.dll` exists.

Example fix

REM before
set ES_JAVA_HOME=C:\Program Files\Java\jre-21
bin\elasticsearch-service.bat install
REM after
set ES_JAVA_HOME=C:\Program Files\Eclipse Adoptium\jdk-21.0.5
bin\elasticsearch-service.bat install
dir "%ES_JAVA_HOME%\bin\server\jvm.dll"
Defensive patterns

Strategy: validation

Validate before calling

Path javaHome = Paths.get(System.getenv("ES_JAVA_HOME"));
Path dll = javaHome.resolve("bin/server/jvm.dll");
if (!Files.isRegularFile(dll)) {
    throw new IllegalStateException("No jvm.dll at " + dll + "; install a full JDK with the server JVM.");
}

Type guard

static boolean hasServerJvm(Path javaHome) {
    return Files.isRegularFile(javaHome.resolve("bin/server/jvm.dll"))
        || Files.isRegularFile(javaHome.resolve("jre/bin/server/jvm.dll"));
}

Try / catch

try {
    installCommand.preExecute(terminal, pinfo, serviceId);
} catch (UserException e) {
    if (e.exitCode == ExitCodes.CONFIG && e.getMessage().contains("jvm.dll")) {
        // direct operator to set ES_JAVA_HOME to a JDK that ships server/jvm.dll
    } else throw e;
}

Prevention

When it happens

Trigger: ES_JAVA_HOME points at a JRE (no server JVM), at a JDK installed without the server JVM, at a Microsoft BuildTools JDK that lacks `server\jvm.dll`, or at a path that is a symlink to the wrong place.

Common situations: Pointing ES_JAVA_HOME at `C:\Program Files\Java\jre-*` instead of a JDK. Using a JDK that only ships the client JVM. Path typos or trailing slashes confusing resolution.

Related errors


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