{"record":{"id":"4750cdff6ef04d45","repo":"elastic/elasticsearch","slug":"starting-java-failed-with-d-output-s-error","errorCode":null,"errorMessage":"starting java failed with [%d]\noutput:\n%s\nerror:\n%s","messagePattern":"starting java failed with \\[(.+?)\\]\noutput:\n(.+?)\nerror:\n(.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"distribution/tools/server-cli/src/main/java/org/elasticsearch/server/cli/JvmOption.java","lineNumber":125,"sourceCode":"            Stream.of(java),\n            userDefinedJvmOptions.stream(),\n            Stream.of(\"-XX:+PrintFlagsFinal\", \"-version\")\n        ).flatMap(Function.identity()).toList();\n        final ProcessBuilder builder = new ProcessBuilder().command(command);\n        setWorkingDir(builder);\n        final Process process = builder.start();\n        final List<String> output = readLinesFromInputStream(process.getInputStream());\n        final List<String> error = readLinesFromInputStream(process.getErrorStream());\n        final int status = process.waitFor();\n        if (status != 0) {\n            final String message = String.format(\n                Locale.ROOT,\n                \"starting java failed with [%d]\\noutput:\\n%s\\nerror:\\n%s\",\n                status,\n                String.join(\"\\n\", output),\n                String.join(\"\\n\", error)\n            );\n            throw new RuntimeException(message);\n        } else {\n            return output;\n        }\n    }\n\n    @SuppressForbidden(reason = \"ProcessBuilder takes File\")\n    private static void setWorkingDir(ProcessBuilder builder) throws IOException {\n        // The real ES process uses the logs dir as the working directory. Since we don't\n        // have the logs dir yet, here we use a temp directory for calculating jvm options.\n        final Path tmpDir = Files.createTempDirectory(\"final-flags\");\n        builder.directory(tmpDir.toFile());\n    }\n\n    private static List<String> readLinesFromInputStream(final InputStream is) throws IOException {\n        try (InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8); BufferedReader br = new BufferedReader(isr)) {\n            return br.lines().toList();\n        }\n    }","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/distribution/tools/server-cli/src/main/java/org/elasticsearch/server/cli/JvmOption.java#L107-L143","documentation":"Thrown by JvmOption's helper that spawns a short-lived Java subprocess (to resolve final JVM flags) when the process exits with a non-zero status. The message embeds the exit code, stdout, and stderr of the failed Java invocation so the underlying JVM error is visible.","triggerScenarios":"ES launches java -version (or an equivalent flag-resolving command) as a subprocess and it exits non-zero — typically because the bundled JDK is broken, a JVM flag is invalid, or the java binary itself fails to start.","commonSituations":"JAVA_HOME points to a corrupt/incompatible JDK; a jvm.options line passes a flag the bundled Java doesn't understand; the java binary is missing or not executable; container image has a broken JDK.","solutions":["Read the embedded 'output:' and 'error:' sections — they contain the actual JVM error (e.g. 'Unrecognized option').","Verify the bundled JDK: $ES_HOME/jdk/bin/java -version runs cleanly.","If using a custom JAVA_HOME, point it at a compatible JDK (see ES supported JDK matrix).","Remove or fix the offending JVM flag identified in the error output."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"Path javaBin = Path.of(installDir, \"jdk\", \"bin\", \"java\");\nif (Files.notExists(javaBin) || !Files.isExecutable(javaBin)) {\n    throw new IllegalStateException(\"Bundled JDK not executable: \" + javaBin);\n}","typeGuard":null,"tryCatchPattern":"try {\n    List<String> out = JvmOption.runJavaForFlags(builder);\n} catch (RuntimeException e) {\n    // message already contains exit code + stdout + stderr; surface to operator.\n    log.error(\"Subprocess java failed: {}\", e.getMessage());\n    throw e;\n}","preventionTips":["Verify the bundled JDK runs: $ES_HOME/jdk/bin/java -version.","If overriding JAVA_HOME, use a JDK from the ES supported matrix.","Validate jvm.options flags against the bundled JDK version before deploy."],"tags":["jvm","jdk","subprocess","startup","config"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}