{"record":{"id":"60cfd0524fac1e9a","repo":"elastic/elasticsearch","slug":"directory-for-entitlement-bridge-jar-does-not-exis","errorCode":null,"errorMessage":"Directory for entitlement bridge jar does not exist: ${dir}","messagePattern":"Directory for entitlement bridge jar does not exist: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"critical","filePath":"distribution/tools/server-cli/src/main/java/org/elasticsearch/server/cli/SystemJvmOptions.java","lineNumber":164,"sourceCode":"        return enableNativeAccessOptions.stream();\n    }\n\n    /*\n     * Only affects 22 and 22.0.1, see https://bugs.openjdk.org/browse/JDK-8329528\n     */\n    @UpdateForV10(owner = UpdateForV10.Owner.CORE_INFRA) // This could be removed when min JDK version = 25\n    private static Stream<String> maybeWorkaroundG1Bug() {\n        Runtime.Version v = Runtime.version();\n        if (v.feature() == 22 && v.update() <= 1) {\n            return Stream.of(\"-XX:+UnlockDiagnosticVMOptions\", \"-XX:G1NumCollectionsKeepPinned=10000000\");\n        }\n        return Stream.of();\n    }\n\n    private static Stream<String> attachEntitlementAgent(Path esHome) {\n        Path dir = esHome.resolve(\"lib/entitlement-bridge\");\n        if (Files.exists(dir) == false) {\n            throw new IllegalStateException(\"Directory for entitlement bridge jar does not exist: \" + dir);\n        }\n        String bridgeJar;\n        try (var s = Files.list(dir)) {\n            var candidates = s.limit(2).toList();\n            if (candidates.size() != 1) {\n                throw new IllegalStateException(\"Expected one jar in \" + dir + \"; found \" + candidates.size());\n            }\n            bridgeJar = candidates.get(0).toString();\n        } catch (IOException e) {\n            throw new IllegalStateException(\"Failed to list entitlement jars in: \" + dir, e);\n        }\n\n        // We instrument classes in these modules to call the bridge. Because the bridge gets patched\n        // into java.base, we must export the bridge from java.base to these modules, as a comma-separated list\n        String modulesContainingEntitlementInstrumentation =\n            \"java.logging,java.net.http,java.naming,jdk.net,jdk.zipfs,jdk.management.agent\";\n        return Stream.of(\n            \"-XX:+EnableDynamicAgentLoading\",","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/distribution/tools/server-cli/src/main/java/org/elasticsearch/server/cli/SystemJvmOptions.java#L146-L182","documentation":"Thrown by SystemJvmOptions.attachEntitlementAgent when the `lib/entitlement-bridge` directory under ES_HOME does not exist. The entitlement bridge is a JVM agent jar that instruments JDK classes to enforce Elasticsearch's runtime entitlement policy; without it the node cannot enforce file/network/process entitlements. The error is an IllegalStateException because a shipped distribution should always contain this directory — its absence indicates a broken or tampered installation.","triggerScenarios":"Running Elasticsearch from a partial extraction of the distribution tarball/zip. A custom distribution that does not stage the entitlement-bridge jar. ES_HOME pointing at the wrong directory (e.g. the source tree rather than a built distribution). Deleting lib/entitlement-bridge manually.","commonSituations":"Operators copy only a subset of files when deploying. CI images built from a truncated `gradlew distribution:zip` output. Source-tree development where the dev runs `bin/elasticsearch` against an unbuilt layout.","solutions":["Confirm ES_HOME points at a complete, freshly extracted distribution: `ls $ES_HOME/lib/entitlement-bridge/`.","Re-extract or reinstall the distribution from an official artifact.","If building from source, run the full distribution build (e.g. `./gradlew :distribution:archives:linux-tar:assemble`) and run from the assembled archive, not the source tree.","Verify no startup script or Dockerfile is deleting lib/entitlement-bridge."],"exampleFix":"# before\nES_HOME=/path/to/partial-extract\n# after\nES_HOME=/path/to/full-elasticsearch-9.0.0\nls $ES_HOME/lib/entitlement-bridge  # should list exactly one jar","handlingStrategy":"validation","validationCode":"Path bridge = esHome.resolve(\"lib/entitlement-bridge\");\nif (!Files.isDirectory(bridge)) {\n    throw new IllegalStateException(\"Missing entitlement-bridge directory at \" + bridge + \"; reinstall the distribution.\");\n}","typeGuard":"static boolean hasEntitlementBridge(Path esHome) {\n    return Files.isDirectory(esHome.resolve(\"lib/entitlement-bridge\"));\n}","tryCatchPattern":"try {\n    List<String> opts = SystemJvmOptions.forEnv(env).getAsArguments();\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"entitlement bridge\")) {\n        // halt deployment; alert ops that the distribution is incomplete\n    } else throw e;\n}","preventionTips":["Extract distributions into a fresh directory per version rather than overlaying.","After extraction, run a smoke check listing lib/entitlement-bridge before starting the node.","In Docker images, COPY the whole distribution and assert the bridge dir exists in a build-time RUN step."],"tags":["cli","entitlements","jvm","installation","startup","agent"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}