{"record":{"id":"c4523a6afdb455bf","repo":"elastic/elasticsearch","slug":"automatic-module-without-a-manifest-name-is-not-su","errorCode":null,"errorMessage":"automatic module without a manifest name is not supported, for: {path}","messagePattern":"automatic module without a manifest name is not supported, for: (.+?)","errorType":"exception","errorClass":"FindException","httpStatus":null,"severity":"error","filePath":"libs/core/src/main/java/org/elasticsearch/core/internal/provider/EmbeddedModulePath.java","lineNumber":62,"sourceCode":"            Optional<ModuleDescriptor> vmd = getModuleInfoVersioned(path);\n            if (vmd.isPresent()) {\n                return vmd.get();\n            } else if (hasRootModuleInfo(path)) {\n                return readModuleInfo(path.resolve(MODULE_INFO), path);\n            } else {\n                return descriptorForAutomatic(path);\n            }\n        } catch (IOException e) {\n            throw new UncheckedIOException(e);\n        }\n    }\n\n    // Generates and returns a module descriptor for an automatic module at the given path.\n    // Currently, only automatic modules with a manifest name are supported.\n    private static ModuleDescriptor descriptorForAutomatic(Path path) throws IOException {\n        String moduleName = moduleNameFromManifestOrNull(path);\n        if (moduleName == null) {\n            throw new FindException(\"automatic module without a manifest name is not supported, for: \" + path);\n        }\n        ModuleDescriptor.Builder builder;\n        try {\n            builder = ModuleDescriptor.newAutomaticModule(moduleName);\n        } catch (IllegalArgumentException e) {\n            throw new FindException(AUTOMATIC_MODULE_NAME + \": \" + e.getMessage());\n        }\n\n        version(path.getFileName().toString()).ifPresent(builder::version);\n\n        // scan the names of the entries in the exploded JAR\n        var scan = scan(path);\n\n        // all packages are exported and open, since the auto-module bit is set\n        String separator = path.getFileSystem().getSeparator();\n        builder.packages(\n            scan.classFiles().stream().map(cf -> toPackageName(cf, separator)).flatMap(Optional::stream).collect(Collectors.toSet())\n        );","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/core/src/main/java/org/elasticsearch/core/internal/provider/EmbeddedModulePath.java#L44-L80","documentation":"Thrown as a FindException by EmbeddedModulePath.descriptorForAutomatic when an automatic module's JAR has no Automatic-Module-Name manifest attribute and no module-info. Elasticsearch's embedded-module path requires automatic modules to declare a manifest name; the fallback to a jar-name-derived module name (which the JDK allows) is deliberately not supported here. FindException signals a module-resolution failure during layer construction.","triggerScenarios":"Loading an embedded provider jar as a module when that jar lacks both module-info.class and an Automatic-Module-Name manifest entry. The descriptorFor path reaches descriptorForAutomatic only after the versioned module-info and root module-info checks fail.","commonSituations":"Vendoring a third-party dependency as an embedded impl jar without adding the manifest attribute. Upgrading a dependency whose newer build dropped the manifest. A custom build that strips manifest attributes during shading. Mixing module-mode providers with classic jars.","solutions":["Add `Automatic-Module-Name: <stable.name>` to the embedded jar's MANIFEST.MF.","If you own the jar, add the attribute in its Gradle/Maven build (jar { manifest { attributes('Automatic-Module-Name': '...') } }).","If the jar is a true module, add a module-info.class instead so descriptorFor takes the module-info branch.","Confirm the jar is meant to be a module-mode provider; non-module providers should not be routed through EmbeddedModulePath."],"exampleFix":"// before — embedded jar has no manifest attribute\n\n// after — in the jar's Gradle build\njar {\n    manifest {\n        attributes('Automatic-Module-Name': 'org.example.mylib')\n    }\n}","handlingStrategy":"validation","validationCode":"// Pre-check a jar for an Automatic-Module-Name (or module-info) before module-mode loading\nboolean isModuleCapableJar(Path jar) throws IOException {\n    try (JarFile j = new JarFile(jar.toFile())) {\n        if (j.getEntry(\"module-info.class\") != null) return true;\n        Manifest m = j.getManifest();\n        return m != null && m.getMainAttributes().getValue(\"Automatic-Module-Name\") != null;\n    }\n}","typeGuard":"static boolean hasAutomaticModuleName(Path jar) throws IOException {\n    try (JarFile j = new JarFile(jar.toFile())) {\n        Manifest m = j.getManifest();\n        return m != null && m.getMainAttributes().getValue(\"Automatic-Module-Name\") != null;\n    }\n}","tryCatchPattern":"try {\n    return EmbeddedModulePath.descriptorFor(path);\n} catch (FindException e) {\n    if (e.getMessage().contains(\"manifest name\")) {\n        // fix: add Automatic-Module-Name to the jar's manifest; do not silently skip\n        throw new RuntimeException(\"jar missing Automatic-Module-Name: \" + path, e);\n    }\n    throw e;\n}","preventionTips":["Add Automatic-Module-Name to any third-party jar before embedding it as a module-mode provider.","In Gradle: jar { manifest { attributes('Automatic-Module-Name': 'stable.name') } }.","Prefer a real module-info.class over an automatic module where possible.","Verify manifests when upgrading dependencies that may have dropped the attribute."],"tags":["modules","classloader","jpms","manifest","provider","elasticsearch-core","packaging"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}