quarkusio/quarkus · error · IllegalArgumentException
Unexpected protocol <protocol> for URL <url>
Error message
Unexpected protocol <protocol> for URL <url>
What it means
processAsPath only supports two URL protocols: nested JAR handling and 'file'. Any other protocol (http, https, jrt, custom) cannot be converted to a filesystem Path, so it throws IllegalArgumentException with the protocol and URL in the message.
Source
Thrown at independent-projects/tools/devtools-common/src/main/java/io/quarkus/platform/descriptor/loader/json/ResourceLoaders.java:77
} 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);
}
private static Path toLocalPath(final URL url) {
try {
return Paths.get(url.toURI());
} catch (URISyntaxException e) {
throw new IllegalArgumentException("Failed to translate " + url + " to local path", e);
}
}
}
View on GitHub (pinned to e1c734241f)
Solutions
- Resolve the resource to a local file first (download/copy it) and pass a file: URL or Path instead
- Check where the URL comes from and use a loader appropriate for that protocol (e.g. URL.openStream for remote resources)
- If this is a Quarkus tool invocation, ensure the descriptor artifact is resolved locally by Maven before descriptor loading
Example fix
// before load(urlFromRemoteRepo); // https URL -> IllegalArgumentException // after Path local = artifactResolver.resolve(artifact).getArtifact().getPath(); load(local.toUri().toURL());
Defensive patterns
Strategy: type-guard
Validate before calling
static boolean supportedUrl(URL url) {
return "file".equals(url.getProtocol()) || "jar".equals(url.getProtocol());
} Type guard
static boolean isFileOrJar(URL url) {
String p = url.getProtocol();
return "file".equals(p) || p.endsWith("jar") || p.endsWith("zip");
} Try / catch
try {
return ResourceLoaders.processAsPath(url, fn);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Unexpected protocol")) {
// download to a temp file and retry with a file URL
return ResourceLoaders.processAsPath(downloadToTempFile(url).toUri().toURL(), fn);
}
throw e;
} Prevention
- Resolve remote artifacts to local files with MavenArtifactResolver before descriptor loading
- Check url.getProtocol() before calling loader APIs
- Avoid classloaders that return http(s)-protocol resource URLs
When it happens
Trigger: Passing a URL with protocol other than 'file' (or a supported jar/zip layout) to loadResourceAsPath/processAsPath — e.g. a URL obtained from an HTTP classloader or a remote repository.
Common situations: Loading platform descriptors from remote Maven repositories over http(s); OSGi or jrt: URLs in modular runtimes; custom URL stream handlers registered by application servers.
Related errors
- Malformed URL: + url
- Failed to compile avro protocole file: ${filePath} to Java
- Invalid external URL, can not be empty
- Value found for #getJarFileUrls : not supported yet
- Value found for #getJtaDataSource : not supported yet
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/364e6ecee5d56049.
Report an issue: GitHub.