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

  1. Ensure providers are loaded from local file or jar URLs — the embedded classloader does not support remote schemes.
  2. If testing, point the codebase at an exploded file directory or a local jar so rootURI yields scheme 'file' or 'jar'.
  3. Inspect the failing provider's CodeSource location (logged upstream) and fix the underlying URL/classpath entry.
  4. 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

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


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/ba70edfcd73e56dc. Report an issue: GitHub.