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

  1. 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.
  2. Verify the providerName passed to ProviderLocator matches the directory under IMPL-JARS/ in the generated resources.
  3. Check that the parent ClassLoader is the one carrying the IMPL resources — a wrong loader will not see them.
  4. 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

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


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/c841de1df96d016c. Report an issue: GitHub.