{"record":{"id":"f9d0d47aeba37d12","repo":"elastic/elasticsearch","slug":"failed-to-transform-jdk-classes-for-entitlements","errorCode":null,"errorMessage":"Failed to transform JDK classes for entitlements","messagePattern":"Failed to transform JDK classes for entitlements","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/DynamicInstrumentation.java","lineNumber":88,"sourceCode":"        inst.addTransformer(transformer, true);\n\n        var classesToRetransform = findClassesToRetransform(inst, inst.getAllLoadedClasses(), classesWithDirectRules);\n        try {\n            inst.retransformClasses(classesToRetransform);\n        } catch (VerifyError e) {\n            // Turn on verification and try to retransform one class at the time to get detailed diagnostic\n            transformer.enableClassVerification();\n\n            for (var classToRetransform : classesToRetransform) {\n                inst.retransformClasses(classToRetransform);\n            }\n\n            // We should have failed already in the loop above, but just in case we did not, rethrow.\n            throw e;\n        }\n\n        if (transformer.hadErrors()) {\n            throw new RuntimeException(\"Failed to transform JDK classes for entitlements\");\n        }\n    }\n\n    /**\n     * Finds already-loaded classes that need retransformation, including subtypes of classes with rules.\n     * Performs a full BFS traversal of each class's hierarchy to check for inherited rules,\n     * so visitation order does not matter.\n     */\n    private static Class<?>[] findClassesToRetransform(Instrumentation inst, Class<?>[] loadedClasses, Set<String> classesWithDirectRules) {\n        List<Class<?>> retransform = new ArrayList<>();\n        for (Class<?> loadedClass : loadedClasses) {\n            if (loadedClass.isHidden()) {\n                continue;\n            }\n            String internalName = loadedClass.getName().replace('.', '/');\n            boolean directMatch = classesWithDirectRules.contains(internalName);\n            if (directMatch == false) {\n                ClassLoader cl = loadedClass.getClassLoader();","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/DynamicInstrumentation.java#L70-L106","documentation":"Thrown by DynamicInstrumentation when the bytecode transformation of JDK classes for entitlement instrumentation reports errors after retransformation. The transformer is asked to retransform classes one at a time for diagnostics; if transformer.hadErrors() is still true after the loop, a RuntimeException is thrown. This indicates the entitlement agent could not instrument the JDK classes it needs to police.","triggerScenarios":"During installEntitlementInstrumentation, inst.retransformClasses throws; the catch enables class verification and retries each class individually, then if transformer.hadErrors() returns true, this exception fires. Causes include unsupported bytecode versions, conflicts with another agent, or a JDK internals layout the transformer cannot handle.","commonSituations":"Running on a JDK version whose internals differ from what the entitlement agent was built for; another javaagent (e.g. APM, profiler) is also instrumenting the same JDK classes and conflicts; a modular JDK denies reflective access the transformer relies on.","solutions":["Use a JDK version that is supported by this Elasticsearch build (check the compatibility matrix).","Remove or disable other javaagents that instrument JDK internals (profilers, coverage, APM) and retry.","Capture the detailed per-class diagnostic printed during the verification-enabled retry loop to identify the offending class, then report or work around it.","Update the Elasticsearch distribution so the bundled entitlement agent matches the running JDK."],"exampleFix":"// before: -javaagent:profiler.jar AND entitlement agent conflict\n\n// after: run without the conflicting agent\njava -jar es.jar   // no extra -javaagent","handlingStrategy":"try-catch","validationCode":"// Probe for conflicting agents and supported JDK before bootstrap\nfor (String a : ManagementFactory.getRuntimeMXBean().getInputArguments()) {\n  if (a.startsWith(\"-javaagent:\")) {\n    // known-OK agents may be allow-listed here\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  EntitlementBootstrap.initialize(...);\n} catch (RuntimeException e) {\n  if (e.getMessage().equals(\"Failed to transform JDK classes for entitlements\")) {\n    // capture transformer diagnostic, remove conflicting -javaagent, or align JDK version\n  }\n  throw e;\n}","preventionTips":["Run only the bundled entitlement agent; remove profiler/APM/coverage javaagents that instrument JDK internals.","Use a JDK version listed in the ES compatibility matrix."],"tags":["entitlement","instrumentation","agent","bytecode","jdk-compat"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:17:08.281Z"}