{"record":{"id":"780fdbfe411ae48c","repo":"elastic/elasticsearch","slug":"unexpected-class-file-version-rawversion-for","errorCode":null,"errorMessage":"Unexpected class file version ${rawVersion} for ${cn.name} (expected ${V21} / JDK 21)","messagePattern":"Unexpected class file version (.+?) for (.+?) \\(expected (.+?) / JDK 21\\)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"critical","filePath":"build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/ExtractForeignApiTask.java","lineNumber":260,"sourceCode":"            cn.innerClasses.removeIf(ic -> (ic.access & Opcodes.ACC_PUBLIC) == 0);\n\n            ClassWriter writer = new ClassWriter(0);\n            cn.accept(writer);\n            return writer.toByteArray();\n        }\n\n        private static List<AnnotationNode> stripPreviewAnnotations(List<AnnotationNode> anns) {\n            if (anns == null) {\n                return null;\n            }\n            anns.removeIf(a -> a.desc.equals(PREVIEW_FEATURE_DESCRIPTOR));\n            return anns.isEmpty() ? null : anns;\n        }\n\n        private static void checkJava21(ClassNode cn) {\n            int rawVersion = cn.version & 0xFFFF;\n            if (rawVersion != V21) {\n                throw new IllegalStateException(\n                    \"Unexpected class file version \" + rawVersion + \" for \" + cn.name + \" (expected \" + V21 + \" / JDK 21)\"\n                );\n            }\n        }\n    }\n}\n","sourceCodeStart":242,"sourceCodeEnd":267,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/ExtractForeignApiTask.java#L242-L267","documentation":"Thrown as IllegalStateException by checkJava21(ClassNode) when (cn.version & 0xFFFF) != V21 (65). Before stripping the preview flag and @PreviewFeature annotations from a java.lang.foreign class, the worker asserts the input class file is exactly major version 65 (JDK 21). A different version means the jrt:/ image is not a JDK 21 image, and the stub-generation logic (which assumes preview semantics) would produce an incorrect JAR.","triggerScenarios":"createStub() (line 205) reads a class from jrt:/modules/java.base/java/lang/foreign, parses it with ASM, and calls checkJava21(cn) at line 209. If the runtime is JDK 21 but the class file's major version isn't 65 — e.g., a backported/custom JDK image, a corrupted module, or an unexpectedly updated JDK where foreign classes shifted versions — the assertion fires.","commonSituations":"Using an early-access or custom-built JDK 21 where class file versions differ; a JDK image patched with classes from a different version; running against a non-standard distribution (GraalVM, Zulu) where foreign package classes carry a different version tag in EA builds.","solutions":["Confirm the JDK 21 in use is a stable GA release (Temurin/Zulu/Corretto 21.x GA) — re-point JAVA_HOME or the toolchain to a GA JDK 21.","Inspect the offending class with javap -v against the JDK image to see its actual major version and confirm whether the image is corrupted.","If the project upgraded the foreign stub expectations, update V21 handling in ExtractForeignApiTask to match the new target version.","Reinstall the JDK 21 installation if a custom/patched module replaced java.base."],"exampleFix":"// before: EA JDK 21 with foreign classes at version 66\n// throws: Unexpected class file version 66 for java/lang/foreign/MemorySegment\n\n// after: switch toolchain to a GA JDK 21 where foreign classes are version 65\njavaToolchainService.launcherFor {\n  it.languageVersion.set(JavaLanguageVersion.of(21))\n  it.vendor.set(JvmVendor.ADOPTIUM)\n}.let { task.getJdk21Launcher().set(it) }","handlingStrategy":"validation","validationCode":"ClassReader reader = new ClassReader(classStream);\nint major = (reader.readUnsignedShort(6)) & 0xFFFF;  // class file major version offset\nif (major != 65 /* V21 */) {\n    throw new IllegalStateException(\"Refusing to process non-JDK21 class file (version \" + major + \")\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use a stable GA JDK 21 (not EA/custom builds) for foreign API stub extraction.","Reinstall the JDK image if java.base was patched or corrupted.","Avoid GraalVM/EA builds for this task unless their class file versions match GA.","Pin the JDK 21 vendor/version in the toolchain spec."],"tags":["build-tooling","foreign-api","asm","classfile","jdk21"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}