{"record":{"id":"4c99a0f1ad5a2732","repo":"elastic/elasticsearch","slug":"unable-to-create-reaper-jar-output-directory","errorCode":null,"errorMessage":"Unable to create reaper JAR output directory {}","messagePattern":"Unable to create reaper JAR output directory (.+?)","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":null,"severity":"error","filePath":"build-tools/src/main/java/org/elasticsearch/gradle/ReaperService.java","lineNumber":146,"sourceCode":"        if (getParameters().getInternal()) {\n            // when running inside the Elasticsearch build just pull find the jar in the runtime classpath\n            URL main = this.getClass().getClassLoader().getResource(REAPER_CLASS);\n            String mainPath = main.getFile();\n            Matcher matcher = REAPER_JAR_PATH_PATTERN.matcher(mainPath);\n\n            if (matcher.matches()) {\n                String path = matcher.group(1);\n                return Path.of(OS.<String>conditional().onWindows(() -> path.substring(1)).onUnix(() -> path).supply());\n            } else {\n                throw new RuntimeException(\"Unable to locate \" + REAPER_CLASS + \" on build classpath.\");\n            }\n        } else {\n            // copy the reaper jar\n            Path jarPath = getParameters().getBuildDir().get().getAsFile().toPath().resolve(\"reaper\").resolve(\"reaper.jar\");\n            try {\n                Files.createDirectories(jarPath.getParent());\n            } catch (IOException e) {\n                throw new UncheckedIOException(\"Unable to create reaper JAR output directory \" + jarPath.getParent(), e);\n            }\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) {","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/build-tools/src/main/java/org/elasticsearch/gradle/ReaperService.java#L128-L164","documentation":"ReaperService.locateReaperJar() throws UncheckedIOException (non-internal mode) when Files.createDirectories(jarPath.getParent()) fails while preparing buildDir/reaper/ to receive the copied reaper.jar. The parent directory is <buildDir>/reaper/; the failure wraps the original IOException with the target path so the filesystem cause (permissions, quota, read-only mount) is identifiable.","triggerScenarios":"Non-internal mode (Params.internal = false): the service tries to materialize buildDir/reaper/reaper.jar from the bundled /META-INF/reaper.jar resource, and creating buildDir/reaper/ fails.","commonSituations":"Read-only build directory (CI with a locked workspace, container with a read-only mount); insufficient permissions on the build dir; disk full or quota exceeded; the buildDir was deleted concurrently; parent path conflicts with an existing file (not a directory).","solutions":["Check the wrapped IOException's message for the filesystem reason (Permission denied, No space left on device, Read-only file system).","Ensure buildDir is writable by the Gradle process and not on a read-only mount.","Free disk space or raise quota if the volume is full.","Remove a conflicting non-directory file at <buildDir>/reaper if one exists.","If running in internal mode is appropriate, switch Params.internal to true to bypass the copy entirely."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"Path reaperDir = buildDir.toPath().resolve(\"reaper\");\nif (!Files.isWritable(buildDir.toPath())) {\n    throw new IllegalStateException(\"buildDir is not writable: \" + buildDir);\n}","typeGuard":null,"tryCatchPattern":"try { Files.createDirectories(reaperDir); } catch (IOException e) { throw new UncheckedIOException(\"Cannot create \" + reaperDir, e); }","preventionTips":["Ensure the build directory is writable and not on a read-only mount.","Free disk space if the volume is full.","Resolve any non-directory file conflicting with <buildDir>/reaper/.","Switch to Params.internal = true to bypass the JAR copy when feasible."],"tags":["gradle","build-tools","reaper","filesystem","io"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}