elastic/elasticsearch · critical · IllegalStateException
missing %s provider jars list
Error message
missing %s provider jars list
What it means
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.
Source
Thrown at libs/core/src/main/java/org/elasticsearch/core/internal/provider/EmbeddedImplClassLoader.java:435
}
});
} catch (IOException x) {
throw new UncheckedIOException(x);
}
return new ScanResult(
Set.copyOf(pkgs),
pkgVersions.entrySet()
.stream() // sort MR JAR prefixes by release number descending
.collect(toUnmodifiableMap(Map.Entry::getKey, v -> v.getValue().stream().sorted(Comparator.reverseOrder()).toList()))
);
}
private static Map<JarMeta, CodeSource> getProviderPrefixes(ClassLoader parent, String providerName) {
String providerPrefix = IMPL_PREFIX + providerName;
InputStream in = parent.getResourceAsStream(providerPrefix + JAR_LISTING_FILE);
if (in == null) {
throw new IllegalStateException(String.format(Locale.ROOT, "missing %s provider jars list", providerName));
}
try (
in;
InputStreamReader isr = new InputStreamReader(in, StandardCharsets.UTF_8);
BufferedReader reader = new BufferedReader(isr)
) {
List<String> jars = reader.lines().toList();
Map<JarMeta, CodeSource> map = new HashMap<>();
for (String jar : jars) {
final CodeSource codeSource = codeSource(parent.getResource(providerPrefix + JAR_LISTING_FILE), jar);
final String jarPrefix = providerPrefix + "/" + jar;
final boolean isMultiRelease = isMultiRelease(parent, jarPrefix);
URI rootURI = rootURI(codeSource.getLocation());
Path p = embeddedJarPath(Set.of(jarPrefix), rootURI)[0];
ScanResult scan;
try {
scan = scanPackages(p, isMultiRelease);
} finally {View on GitHub (pinned to db6a809a66)
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.
Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight: confirm the provider jar listing resource is present
boolean hasProviderListing(ClassLoader parent, String providerName) {
String p = "META-INF/impl-jars/" + providerName + "/jar-listing.txt"; // path per IMPL_PREFIX/JAR_LISTING_FILE
return parent.getResourceAsStream(p) != null;
} Type guard
// not a type-narrowing case; this is a packaging invariant
static boolean providerIsPackaged(ClassLoader cl, String name) {
return cl.getResourceAsStream("META-INF/impl-jars/" + name) != null;
} Try / catch
try {
return new ProviderLocator<>(name, type, moduleName, missingModules).get();
} catch (IllegalStateException e) {
if (e.getMessage().contains("provider jars list")) {
// instruct: rebuild the module to generate the IMPL listing; do not retry blindly
throw new RuntimeException("Provider [" + name + "] not packaged; run the build's impl-jars task", e);
}
throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- unknown scheme:{rootURI.getScheme()}
- automatic module without a manifest name is not supported, f
- Automatic-Module-Name: {e.getMessage()}
- unexpected jar name: {jarName}
- {name} found in top-level directory (unnamed package not all
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/c841de1df96d016c.
Report an issue: GitHub.