quarkusio/quarkus · error · RuntimeException
Failed to create a URL for '<file>'
Error message
Failed to create a URL for '<file>'
What it means
ResourceLoaders.processAsPath resolves a resource URL into a filesystem Path so a consumer function can read it. When the URL points inside a nested JAR, it strips the '!...' suffix and converts the JAR URL to a local Path; if that sub-URL is malformed (cannot be parsed as a URL), a RuntimeException wrapping MalformedURLException is thrown with this message.
Source
Thrown at independent-projects/tools/devtools-common/src/main/java/io/quarkus/platform/descriptor/loader/json/ResourceLoaders.java:60
if (f.isDirectory()) {
return new DirectoryResourceLoader(f.toPath());
}
if (f.isFile() && FilenameUtils.isExtension(f.getName(), "jar", "zip")) {
return new ZipResourceLoader(f.toPath());
}
throw new IllegalStateException("No compatible ResourceLoader have been found for file type: " + f.getName());
}
// This method is copied from io.quarkus.runtime.util.ClassPathUtils
public static <R> R processAsPath(URL url, Function<Path, R> function) {
if (JAR.equals(url.getProtocol())) {
final String file = url.getFile();
final int exclam = file.lastIndexOf('!');
final Path jar;
try {
jar = toLocalPath(exclam >= 0 ? new URL(file.substring(0, exclam)) : url);
} catch (MalformedURLException e) {
throw new RuntimeException("Failed to create a URL for '" + file.substring(0, exclam) + "'", e);
}
try (FileSystem jarFs = ZipUtils.newFileSystem(jar)) {
Path localPath = jarFs.getPath("/");
if (exclam >= 0) {
localPath = localPath.resolve(file.substring(exclam + 1));
}
return function.apply(localPath);
} catch (IOException e) {
throw new UncheckedIOException("Failed to read " + jar, e);
}
}
if (FILE.equals(url.getProtocol())) {
return function.apply(toLocalPath(url));
}
throw new IllegalArgumentException("Unexpected protocol " + url.getProtocol() + " for URL " + url);
}View on GitHub (pinned to e1c734241f)
Solutions
- Print the offending URL and check the text before the last '!' is a fully-formed URL with scheme (e.g. file:/path/to.jar)
- Fix the code that constructed the URL so the JAR part includes its scheme (prepend 'file:' if it came from a raw path)
- If the resource is on the local filesystem, ensure it is passed as a 'file:' URL so the FILE protocol branch is used instead of the nested-JAR branch
Example fix
// before
URL url = new URL("/opt/app/lib/quarkus.jar!/quarkus-extension.yaml"); // MalformedURLException downstream
// after
URL url = new URL("file:/opt/app/lib/quarkus.jar!/quarkus-extension.yaml"); Defensive patterns
Strategy: validation
Validate before calling
static boolean safeNestedJarUrl(URL url) {
String f = url.getFile();
int exclam = f.lastIndexOf('!');
if (exclam < 0) return true;
try { new URL(f.substring(0, exclam)); return true; }
catch (MalformedURLException e) { return false; }
} Type guard
static boolean hasJarScheme(URL url) {
String f = url.getFile();
int i = f.lastIndexOf('!');
return i < 0 || f.startsWith("file:", 0) && i > "file:".length();
} Try / catch
try {
ResourceLoaders.processAsPath(url, fn);
} catch (RuntimeException e) {
if (e.getCause() instanceof MalformedURLException) {
throw new IllegalStateException("Malformed nested-jar URL: " + url, e);
}
throw e;
} Prevention
- Build URLs with File.toURI().toURL() or Path.toUri().toURL(), never string concatenation
- Only pass jar-style URLs produced by standard classloaders into ResourceLoaders
- Log the full URL before processing so malformed pieces are visible in failures
When it happens
Trigger: Calling loadResourceAsPath/processAsPath with a URL whose file portion contains a '!' but whose part before the last '!' is not a valid URL (e.g. a plain path 'file1.jar' with no scheme, or an improperly encoded URL string).
Common situations: Spring Boot-style fat/nested JARs (jar:file:...!/...!/...) where the nested entry is extracted incorrectly; custom classloaders constructing non-standard 'jar:' URLs; corrupted MANIFEST classpath entries with malformed jar paths.
Related errors
- Failed to translate
- Failed to read
- Failed to create an instance of java.nio.file.Path from <url
- There were a problem while reading the resource dir '<name>'
- Expected : after attribute
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/381f7c3b0192072b.
Report an issue: GitHub.