elastic/elasticsearch · error · GradleException

module-info.class no found in ${path}

Error message

module-info.class no found in ${path}

What it means

Thrown as GradleException by assertAllESJarsAreModular() when an Elasticsearch JAR (name starting 'elasticsearch-', excluding elasticsearch-log4j) in the lib/ directory does not contain a module-info.class entry at its root. ES server jars must be modular JPMS modules; a missing module-info means the jar was built without module info, breaking the module system checks and runtime module resolution. Note: the message has a typo ('no found' instead of 'not found').

Source

Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/InternalDistributionModuleCheckTaskProvider.java:119

                    try {
                        assertAllESJarsAreModular(libPath);
                        assertAllModulesPresent(libPath);
                    } catch (IOException e) {
                        throw new UncheckedIOException(e);
                    }
                }
            });
        });
    }

    /** Checks that all expected ES jar files are modular, i.e. contain a module-info.class in their root. */
    private static void assertAllESJarsAreModular(Path libPath) throws IOException {
        try (var s = Files.walk(libPath, 1)) {
            s.filter(Files::isRegularFile).filter(isESJar).filter(isNotExcluded).sorted().forEach(path -> {
                try (JarFile jf = new JarFile(path.toFile())) {
                    JarEntry entry = jf.getJarEntry(MODULE_INFO);
                    if (entry == null) {
                        throw new GradleException(MODULE_INFO + " no found in " + path);
                    }
                } catch (IOException e) {
                    throw new GradleException("Failed when reading jar file " + path, e);
                }
            });
        }
    }

    /** Checks that all expected Elasticsearch modules are present. */
    private static void assertAllModulesPresent(Path libPath) {
        List<String> actualESModules = ModuleFinder.of(libPath).findAll().stream().filter(isESModule).map(toName).sorted().toList();
        if (actualESModules.equals(EXPECTED_ES_SERVER_MODULES) == false) {
            throw new GradleException(
                "expected modules " + listToString(EXPECTED_ES_SERVER_MODULES) + ", \nactual modules " + listToString(actualESModules)
            );
        }
    }

View on GitHub (pinned to db6a809a66)

Solutions

  1. Add a module-info.java to the source set of the project producing the offending jar.
  2. Ensure the project applies the ES module/plugin conventions that generate module-info.class during jar task.
  3. If the jar is legitimately non-modular, add its name prefix to ES_JAR_EXCLUDES (currently only elasticsearch-log4j).
  4. Rebuild the jar task and verify with 'jar tf <jar> | grep module-info.class'.

Example fix

// before: new subproject jar lacks module-info
evaluationDependsOn(':libs:elasticsearch-newlib')
// jar contains no module-info.class → throws

// after: add module-info.java to src/main/java
// module org.elasticsearch.newlib { exports org.elasticsearch.newlib; }
// and ensure the jar task includes it (default for src/main/java)
Defensive patterns

Strategy: validation

Validate before calling

try (JarFile jf = new JarFile(path.toFile())) {
    if (jf.getJarEntry("module-info.class") == null) {
        System.err.println("WARNING: " + path + " is not modular (no module-info.class)");
    }
}

Prevention

When it happens

Trigger: assertAllESJarsAreModular (line 113) walks lib/ depth 1, filters for regular files starting with 'elasticsearch-' (excluding 'elasticsearch-log4j'), opens each as a JarFile, and checks getJarEntry("module-info.class"). A null entry throws at line 119.

Common situations: A new ES subproject jar was added to the distribution but its build.gradle doesn't apply the module plugin or generate module-info; a third-party shadow jar was renamed to start with 'elasticsearch-'; the modularization step was skipped in the build; refactoring merged a module into a non-modular jar.

Related errors


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