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

  1. Resolve the resource to a local file first (download/copy it) and pass a file: URL or Path instead
  2. Check where the URL comes from and use a loader appropriate for that protocol (e.g. URL.openStream for remote resources)
  3. 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

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


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/364e6ecee5d56049. Report an issue: GitHub.