quarkusio/quarkus · error · IllegalStateException
Cannot determine image path (image path)
Error message
Cannot determine image path (image path)
What it means
Immediately after resolving the bin directory, the launcher takes its parent as the image root. If binPath.getParent() returns null (bin is a filesystem root), the image path cannot be determined and the launcher aborts. A sibling error 'Cannot determine image path (bin path)' covers the case where the parent isn't named 'bin'.
Source
Thrown at extensions/packaging/jlink/launcher/src/main/java/io/quarkus/jlink/launcher/JLinkAppLauncher.java:48
ModuleLayer myLayer = myModule.getLayer();
if (myLayer == null) {
throw new IllegalStateException("Module of jlink image launcher is not in a module layer");
}
@SuppressWarnings("resource")
ModuleLoader base = ModuleLoader.forLayer("base", myLayer);
// try to ascertain our own path
String cmd = ProcessHandle.current().info().command()
.orElseThrow(() -> new IllegalStateException("Cannot determine image path (ProcessHandle)"));
Path cmdPath = Path.of(cmd);
Path binPath = cmdPath.getParent();
if (binPath == null || !binPath.getFileName().toString().equals("bin")) {
throw new IllegalStateException("Cannot determine image path (bin path)");
}
Path imagePath = binPath.getParent();
if (imagePath == null) {
throw new IllegalStateException("Cannot determine image path (image path)");
}
Path libPath = imagePath.resolve("lib").resolve("quarkus");
// create a layer for our dynamic modules
ModuleLoader dyn = new ModuleLoader("dyn", ModuleFinder.fromFileSystem(List.of(libPath))) {
public LoadedModule loadModule(final String moduleName) {
LoadedModule found = base.loadModule(moduleName);
if (found == null) {
found = super.loadModule(moduleName);
}
return found;
}
};
// load the application
LoadedModule loadedModule = dyn.loadModule(appModule);
if (loadedModule == null) {View on GitHub (pinned to e1c734241f)
Solutions
- Restore the standard image layout so the launcher lives at <image>/bin/<name> with a non-root parent
- Run from an installed image directory, not a chroot/mount where bin is the filesystem root
- Regenerate the jlink image with the Quarkus jlink packaging extension
Example fix
null
Defensive patterns
Strategy: validation
Validate before calling
Path binPath = Path.of(
ProcessHandle.current().info().command().orElseThrow()).getParent();
if (binPath == null || binPath.getParent() == null) {
throw new IllegalStateException("bin directory has no parent; invalid image layout");
} Type guard
boolean hasImageRoot(Path binDir) {
return binDir.getParent() != null;
} Try / catch
try {
JLinkAppLauncher.run(appModule, args);
} catch (IllegalStateException e) {
if (e.getMessage().contains("image path")) {
throw new IllegalStateException("Image layout invalid; regenerate the image", e);
}
throw e;
} Prevention
- Keep the executable nested at least one level below the filesystem root
- Regenerate images with the Quarkus jlink extension rather than hand-editing layouts
- Avoid chroot/mount setups that place bin at the root
When it happens
Trigger: The launcher executable sits directly at a filesystem root (its bin directory has no parent) — an essentially impossible layout for a real jlink image.
Common situations: Highly contrived setups where the executable is mounted/chrooted at /bin of a root namespace or a sandbox flattens the image layout to the root.
Related errors
- Cannot determine image path (bin path)
- Must launch jlink image in module mode only
- Module of jlink image launcher is not in a module layer
- Unable to find command: %s in $PATH: %s
- Docker Compose not found. Is ${composeExecutable} on the PAT
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/0f7739e7fc1f151b.
Report an issue: GitHub.