{"record":{"id":"c841de1df96d016c","repo":"elastic/elasticsearch","slug":"missing-s-provider-jars-list","errorCode":null,"errorMessage":"missing %s provider jars list","messagePattern":"missing (.+?) provider jars list","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"critical","filePath":"libs/core/src/main/java/org/elasticsearch/core/internal/provider/EmbeddedImplClassLoader.java","lineNumber":435,"sourceCode":"                }\n            });\n        } catch (IOException x) {\n            throw new UncheckedIOException(x);\n        }\n\n        return new ScanResult(\n            Set.copyOf(pkgs),\n            pkgVersions.entrySet()\n                .stream() // sort MR JAR prefixes by release number descending\n                .collect(toUnmodifiableMap(Map.Entry::getKey, v -> v.getValue().stream().sorted(Comparator.reverseOrder()).toList()))\n        );\n    }\n\n    private static Map<JarMeta, CodeSource> getProviderPrefixes(ClassLoader parent, String providerName) {\n        String providerPrefix = IMPL_PREFIX + providerName;\n        InputStream in = parent.getResourceAsStream(providerPrefix + JAR_LISTING_FILE);\n        if (in == null) {\n            throw new IllegalStateException(String.format(Locale.ROOT, \"missing %s provider jars list\", providerName));\n        }\n        try (\n            in;\n            InputStreamReader isr = new InputStreamReader(in, StandardCharsets.UTF_8);\n            BufferedReader reader = new BufferedReader(isr)\n        ) {\n            List<String> jars = reader.lines().toList();\n            Map<JarMeta, CodeSource> map = new HashMap<>();\n            for (String jar : jars) {\n                final CodeSource codeSource = codeSource(parent.getResource(providerPrefix + JAR_LISTING_FILE), jar);\n                final String jarPrefix = providerPrefix + \"/\" + jar;\n                final boolean isMultiRelease = isMultiRelease(parent, jarPrefix);\n                URI rootURI = rootURI(codeSource.getLocation());\n                Path p = embeddedJarPath(Set.of(jarPrefix), rootURI)[0];\n                ScanResult scan;\n                try {\n                    scan = scanPackages(p, isMultiRelease);\n                } finally {","sourceCodeStart":417,"sourceCodeEnd":453,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/core/src/main/java/org/elasticsearch/core/internal/provider/EmbeddedImplClassLoader.java#L417-L453","documentation":"Thrown as an IllegalStateException by EmbeddedImplClassLoader.getProviderPrefixes when parent.getResourceAsStream for the provider's jar-listing resource returns null. Each provider ships a manifest file (under IMPL-JARS/<providerName>/...) enumerating its embedded jars; if that resource is absent the classloader cannot enumerate provider jars and refuses to proceed. This indicates a packaging or build-output problem, not a runtime config one.","triggerScenarios":"Requesting a provider whose embedded jar listing was not generated. Occurs when the build skipped the ImplJarsTask for a module, when the provider name is misspelled relative to the generated path, or when running against a partial/stale build output directory.","commonSituations":"A developer runs tests with an incomplete `./gradlew` invocation that did not generate IMPL resources. Adding a new SPI provider but forgetting to register it in the module's impl-jars generation. Pointing an IDE classpath at build output from a different branch. Renaming a provider module without updating the listing path.","solutions":["Run a clean build of the affected module (e.g. `./gradlew :libs:<module>:build` or the relevant generateImplJars task) so the listing resource is emitted.","Verify the providerName passed to ProviderLocator matches the directory under IMPL-JARS/ in the generated resources.","Check that the parent ClassLoader is the one carrying the IMPL resources — a wrong loader will not see them.","If the module legitimately has no embedded jars, confirm whether it should be registered as a provider at all."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Pre-flight: confirm the provider jar listing resource is present\nboolean hasProviderListing(ClassLoader parent, String providerName) {\n    String p = \"META-INF/impl-jars/\" + providerName + \"/jar-listing.txt\"; // path per IMPL_PREFIX/JAR_LISTING_FILE\n    return parent.getResourceAsStream(p) != null;\n}","typeGuard":"// not a type-narrowing case; this is a packaging invariant\nstatic boolean providerIsPackaged(ClassLoader cl, String name) {\n    return cl.getResourceAsStream(\"META-INF/impl-jars/\" + name) != null;\n}","tryCatchPattern":"try {\n    return new ProviderLocator<>(name, type, moduleName, missingModules).get();\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"provider jars list\")) {\n        // instruct: rebuild the module to generate the IMPL listing; do not retry blindly\n        throw new RuntimeException(\"Provider [\" + name + \"] not packaged; run the build's impl-jars task\", e);\n    }\n    throw e;\n}","preventionTips":["Run a clean build of modules whose providers you load so IMPL resources are generated.","Keep provider names consistent between ProviderLocator and the IMPL-JARS directory.","Don't run against stale/partial build output directories.","When adding a new SPI provider, register it in the module's impl-jars generation."],"tags":["classloader","modules","provider","build","packaging","elasticsearch-core","spi"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}