elastic/elasticsearch · error · IOException
unknown scheme:{rootURI.getScheme()}
Error message
unknown scheme:{rootURI.getScheme()} What it means
Thrown as an IOException by EmbeddedImplClassLoader.embeddedJarPath when the root URI of a provider's codebase has neither a 'file' nor a 'jar' scheme. The embedded classloader supports exactly these two: 'file' for exploded/test layouts and 'jar:file' for packaged distributions. Any other scheme (http, https, ftp, custom) indicates a misconfigured or corrupted classpath URL and is rejected.
Source
Thrown at libs/core/src/main/java/org/elasticsearch/core/internal/provider/EmbeddedImplClassLoader.java:336
private Path[] modulePath() throws IOException {
URI rootURI = rootURI(prefixToCodeBase.values().stream().findFirst().map(CodeSource::getLocation).orElseThrow());
return embeddedJarPath(prefixToCodeBase.keySet(), rootURI);
}
private static Path[] embeddedJarPath(Set<String> prefixes, URI rootURI) throws IOException {
Function<Path, Path[]> entries = path -> prefixes.stream()
.map(EmbeddedImplClassLoader::basePrefix)
.distinct()
.map(pfx -> path.resolve(pfx))
.toArray(Path[]::new);
if (rootURI.getScheme().equals("file")) {
return entries.apply(Path.of(rootURI));
} else if (rootURI.getScheme().equals("jar")) {
FileSystem fileSystem = FileSystems.newFileSystem(rootURI, Map.of(), ClassLoader.getSystemClassLoader());
Path rootPath = fileSystem.getPath("/");
return entries.apply(rootPath);
} else {
throw new IOException("unknown scheme:" + rootURI.getScheme());
}
}
// -- infra
/**
* Returns the root URI for a given url. The root URI is the base URI where all classes and
* resources can be searched for by appending a prefixes.
*
* Depending on whether running from a jar (distribution), or an exploded archive (testing),
* the given url will have one of two schemes, "file", or "jar:file". For example:
* distro- jar:file:/xxx/distro/lib/elasticsearch-x-content-8.2.0-SNAPSHOT.jar!/IMPL-JARS/x-content/xlib-2.10.4.jar
* rootURI jar:file:/xxx/distro/lib/elasticsearch-x-content-8.2.0-SNAPSHOT.jar
*
* test - file:/x/git/es_modules/libs/x-content/build/generated-resources/impl/IMPL-JARS/x-content/xlib-2.10.4.jar
* rootURI file:/x/git/es_modules/libs/x-content/build/generated-resources/impl
*/
static URI rootURI(URL url) {View on GitHub (pinned to db6a809a66)
Solutions
- Ensure providers are loaded from local file or jar URLs — the embedded classloader does not support remote schemes.
- If testing, point the codebase at an exploded file directory or a local jar so rootURI yields scheme 'file' or 'jar'.
- Inspect the failing provider's CodeSource location (logged upstream) and fix the underlying URL/classpath entry.
- For a packaging bug, rebuild the distribution so provider jars are nested correctly under IMPL-JARS.
Defensive patterns
Strategy: validation
Validate before calling
// Validate the scheme before constructing/using the embedded classloader
static void requireLocalScheme(URI root) {
if (!"file".equals(root.getScheme()) && !"jar".equals(root.getScheme())) {
throw new IllegalArgumentException("unsupported codebase scheme: " + root.getScheme());
}
} Type guard
static boolean isSupportedCodebaseScheme(URI uri) {
String s = uri.getScheme();
return "file".equals(s) || "jar".equals(s);
} Try / catch
try {
return embeddedJarPath(prefixes, rootURI);
} catch (IOException e) {
// log the offending URI and surface; embedded loading does not support remote schemes
throw new IllegalStateException("cannot load provider from " + rootURI, e);
} Prevention
- Load providers only from local file: or jar:file: URLs.
- In tests, point provider codebases at exploded directories or local jars.
- Inspect CodeSource locations before constructing EmbeddedImplClassLoader.
- Keep distribution packaging so provider jars nest correctly under IMPL-JARS.
When it happens
Trigger: A provider's CodeSource location resolves to a URI with an unsupported scheme — for example, a remote URL injected via a custom classloader, or a malformed jar: URL whose scheme extraction yields something unexpected. The check at line 329/331 only matches 'file' and 'jar'.
Common situations: A plugin or test harness constructing a URLClassLoader with http(s) URLs and routing it through EmbeddedImplClassLoader. A build artifact whose location URL is jar: but the rootURI helper returns a wrong scheme after substring extraction. Running from an unsupported container/runtime that reports a non-standard protocol.
Related errors
- missing %s provider jars list
- automatic module without a manifest name is not supported, f
- Automatic-Module-Name: {e.getMessage()}
- unexpected jar name: {jarName}
- {name} found in top-level directory (unnamed package not all
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/ba70edfcd73e56dc.
Report an issue: GitHub.