elastic/elasticsearch · error · GradleException

expected modules , actual modules

Error message

expected modules ${listToString(EXPECTED_ES_SERVER_MODULES)}, 
actual modules ${listToString(actualESModules)}

What it means

Thrown as GradleException by assertAllModulesPresent() when the set of ES modules discovered by ModuleFinder.of(libPath).findAll() (filtered to names starting 'org.elasticsearch') does not exactly equal EXPECTED_ES_SERVER_MODULES. This is an exact-set equality check — any added, removed, or renamed module fails it. The constant list is the authoritative manifest of modules that must ship in the ES server distribution.

Solutions

  1. Compare the 'expected' vs 'actual' lists in the error message — the diff shows exactly which module was added or removed.
  2. If a module was legitimately added, append its name to EXPECTED_ES_SERVER_MODULES in this file (line 52).
  3. If a module is unexpectedly missing, investigate why its jar didn't build or isn't in lib/ (check the jar task and distribution assembly).
  4. If a module was renamed, update both the module-info.java and EXPECTED_ES_SERVER_MODULES to the new name.

Example fix

// before: new module org.elasticsearch.newfeature built but not in expected list
// throws: expected modules [...], actual modules [...org.elasticsearch.newfeature...]

// after: add the module name to the expected list
private static final List<String> EXPECTED_ES_SERVER_MODULES = List.of(
    // ...
    "org.elasticsearch.newfeature",
    "org.elasticsearch.xcontent"
);
Defensive patterns

Strategy: validation

Validate before calling

List<String> actual = ModuleFinder.of(libPath).findAll().stream()
    .map(m -> m.descriptor().name()).filter(n -> n.startsWith("org.elasticsearch")).sorted().toList();
List<String> missing = new ArrayList<>(EXPECTED_ES_SERVER_MODULES); missing.removeAll(actual);
List<String> extra = new ArrayList<>(actual); extra.removeAll(EXPECTED_ES_SERVER_MODULES);
if (missing.isEmpty() == false || extra.isEmpty() == false) {
    System.err.println("Module mismatch — missing: " + missing + ", extra: " + extra);
}

Prevention

When it happens

Trigger: assertAllModulesPresent (line 129) collects actual module names, sorts, and compares with .equals against the static EXPECTED_ES_SERVER_MODULES list (line 52). A new module added without updating the list, a module renamed, or a module missing from the build all cause inequality and throw.

Common situations: A new ES module was added to the build (e.g., org.elasticsearch.newfeature) but EXPECTED_ES_SERVER_MODULES wasn't updated; a module was renamed or removed; a module failed to build and is absent from lib/; a module was accidentally split into two.

Related errors


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

Appendix: source

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

        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)
            );
        }
    }

    // ####: eventually assert hashes, etc

    static String listToString(List<String> list) {
        return list.stream().sorted().collect(joining("\n  ", "[\n  ", "]"));
    }
}

View on GitHub (pinned to db6a809a66)