| Issue | Common Cause | Primary Fix |
|---|---|---|
| jlink Error: module not found | Missing --module-path or non-modular JARs. |
Point to the jmods folder and use jdeps to map dependencies. |

What is the Java 21 jlink “module not found” Error?
The jlink tool in Java 21 allows developers to create a custom, lightweight JRE by assembling only the necessary modules for an application. This reduces the deployment size significantly.
The “module not found” error occurs when the linker cannot locate a specific module defined in your module-info.java or specified in the command line. This usually happens because the module path is incorrectly configured or the dependency is not a true JPMS module.
In Java 21, strict modularity is enforced. If jlink encounters an “automatic module” (a plain JAR file without a module descriptor), it will fail because jlink does not support linking automatic modules into a custom image.
Step-by-Step Solutions
1. Verify the Module Path
The most common cause is failing to include the JDK’s own modules in the path. You must explicitly point to the jmods directory of your JDK installation.
jlink --module-path $JAVA_HOME/jmods:out/modules \
--add-modules com.example.myapp \
--output custom-runtime
On Windows, ensure you use a semicolon (;) instead of a colon (:) as the path separator.
2. Identify Missing Dependencies with jdeps
If you aren’t sure which module is missing, use the jdeps tool. It analyzes your JAR files and tells you exactly which modules are required.
jdeps --module-path libs/ --print-module-deps my-app.jar
Review the output and ensure every module listed is included in your --add-modules flag or is present in your --module-path.
3. Handling Non-Modular JARs (Automatic Modules)
If your error involves a third-party library that isn’t modularized, jlink will throw an error. You have two options: use a tool like Moditect to generate a module-info.class for the library, or use a “fat JAR” approach with a standard JRE.
To fix this for jlink, you must convert the JAR to a module. You can do this manually by creating a temporary module-info.java for the dependency and recompiling it.
4. Check for Case Sensitivity and Typos
Java module names are case-sensitive. A common mistake is writing java.Xml instead of java.xml. Double-check your module-info.java file for any typos in the requires directives.
module com.example.myapp {
requires java.base;
requires java.logging; // Ensure these names match the JDK modules
}
5. Use the –limit-modules Flag for Debugging
If you are overwhelmed by the dependency graph, use --limit-modules to restrict the observable modules. This helps isolate whether the error is coming from your application code or a secondary dependency.