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
- Verify the dll exists: `dir "%ES_JAVA_HOME%\bin\server\jvm.dll"`.
- Install a full JDK (e.g. Eclipse Temurin JDK) that ships the server JVM.
- Set ES_JAVA_HOME to the JDK root (the directory containing bin/, lib/, conf/).
- 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
- Point ES_JAVA_HOME at a JDK (not a JRE) that ships the server JVM, e.g. Eclipse Temurin.
- Add a preflight `dir "%ES_JAVA_HOME%\bin\server\jvm.dll"` to install scripts.
- Avoid Microsoft BuildTools distributions which may omit the server JVM.
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
- Missing procrun exe: ${procrun}
- Elasticsearch died while starting up, exit code: ${exitCode}
- could not create the default ssl context
- Directory for entitlement bridge jar does not exist: ${dir}
- Expected one jar in ${dir}; found ${candidates.size()}
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/ceedf9acb3a16b2b.
Report an issue: GitHub.