{"record":{"id":"978b1ded768e45c4","repo":"elastic/elasticsearch","slug":"reaper-process-died-unexpectedly-check-the-log-at","errorCode":null,"errorMessage":"Reaper process died unexpectedly! Check the log at {}","messagePattern":"Reaper process died unexpectedly! Check the log at (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"build-tools/src/main/java/org/elasticsearch/gradle/ReaperService.java","lineNumber":165,"sourceCode":"            }\n\n            try (\n                OutputStream out = Files.newOutputStream(jarPath);\n                InputStream jarInput = this.getClass().getResourceAsStream(\"/META-INF/reaper.jar\");\n            ) {\n                logger.info(\"Copying reaper.jar...\");\n                jarInput.transferTo(out);\n            } catch (IOException e) {\n                throw new UncheckedIOException(e);\n            }\n\n            return jarPath;\n        }\n    }\n\n    private void ensureReaperAlive() {\n        if (reaperProcess.isAlive() == false) {\n            throw new IllegalStateException(\"Reaper process died unexpectedly! Check the log at \" + logFilePath().toString());\n        }\n    }\n\n    @Override\n    public void close() throws Exception {\n        shutdown();\n    }\n\n    public interface Params extends BuildServiceParameters {\n        Boolean getInternal();\n\n        void setInternal(Boolean internal);\n\n        DirectoryProperty getBuildDir();\n\n        DirectoryProperty getInputDir();\n    }\n}","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/build-tools/src/main/java/org/elasticsearch/gradle/ReaperService.java#L147-L183","documentation":"ReaperService.ensureReaperAlive() throws IllegalStateException when reaperProcess.isAlive() is false. This is checked before issuing commands to the reaper (registerCommand, registerPid) and during shutdown. It means the reaper JVM launched in ensureReaperStarted() has exited while the Gradle build is still expecting it to be available — i.e., the reaper crashed. The log at <inputDir>/reaper.log has the reaper's output.","triggerScenarios":"After the reaper process is started, any subsequent call to ensureReaperStarted() (which calls ensureReaperAlive() on the existing process) or shutdown() (via ensureReaperAlive()) finds the process dead. Also fires if registerPid/registerCommand is called after a crash.","commonSituations":"The reaper JVM crashed with an uncaught exception (OOM due to -Xmx16m being too small for a pathological input, a bug in the reaper); the reaper was killed externally (OOM killer, manual kill, container reap); the reaper exited normally but a stale reference is being used.","solutions":["Read reaper.log at the path in the exception (typically .gradle/reaper/build-<pid>/reaper.log) for the crash cause.","If the reaper is OOMing, investigate the .cmd workload or the reaper's heap budget.","Check dmesg/system logs for OOM-killer or external signal delivery to the reaper PID.","Re-run the build; transient reaper crashes (e.g., external kill) are often non-reproducible."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { reaperService.registerCommand(id, cmd); } catch (IllegalStateException e) { /* reaper died; read reaper.log */ Path log = Path.of(e.getMessage().replaceAll(\".*log at \", \"\")); throw e; }","preventionTips":["Inspect reaper.log at the path in the exception for the crash cause.","Investigate OOM-killer or external signals if the reaper JVM is being killed.","Re-run the build — transient external kills are often non-reproducible."],"tags":["gradle","build-tools","reaper","subprocess-failure"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}