{"record":{"id":"ba70edfcd73e56dc","repo":"elastic/elasticsearch","slug":"unknown-scheme-rooturi-getscheme","errorCode":null,"errorMessage":"unknown scheme:{rootURI.getScheme()}","messagePattern":"unknown scheme:(.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"libs/core/src/main/java/org/elasticsearch/core/internal/provider/EmbeddedImplClassLoader.java","lineNumber":336,"sourceCode":"    private Path[] modulePath() throws IOException {\n        URI rootURI = rootURI(prefixToCodeBase.values().stream().findFirst().map(CodeSource::getLocation).orElseThrow());\n        return embeddedJarPath(prefixToCodeBase.keySet(), rootURI);\n    }\n\n    private static Path[] embeddedJarPath(Set<String> prefixes, URI rootURI) throws IOException {\n        Function<Path, Path[]> entries = path -> prefixes.stream()\n            .map(EmbeddedImplClassLoader::basePrefix)\n            .distinct()\n            .map(pfx -> path.resolve(pfx))\n            .toArray(Path[]::new);\n        if (rootURI.getScheme().equals(\"file\")) {\n            return entries.apply(Path.of(rootURI));\n        } else if (rootURI.getScheme().equals(\"jar\")) {\n            FileSystem fileSystem = FileSystems.newFileSystem(rootURI, Map.of(), ClassLoader.getSystemClassLoader());\n            Path rootPath = fileSystem.getPath(\"/\");\n            return entries.apply(rootPath);\n        } else {\n            throw new IOException(\"unknown scheme:\" + rootURI.getScheme());\n        }\n    }\n\n    // -- infra\n\n    /**\n     * Returns the root URI for a given url. The root URI is the base URI where all classes and\n     * resources can be searched for by appending a prefixes.\n     *\n     * Depending on whether running from a jar (distribution), or an exploded archive (testing),\n     * the given url will have one of two schemes, \"file\", or \"jar:file\". For example:\n     *  distro- jar:file:/xxx/distro/lib/elasticsearch-x-content-8.2.0-SNAPSHOT.jar!/IMPL-JARS/x-content/xlib-2.10.4.jar\n     *  rootURI jar:file:/xxx/distro/lib/elasticsearch-x-content-8.2.0-SNAPSHOT.jar\n     *\n     *  test  - file:/x/git/es_modules/libs/x-content/build/generated-resources/impl/IMPL-JARS/x-content/xlib-2.10.4.jar\n     *  rootURI file:/x/git/es_modules/libs/x-content/build/generated-resources/impl\n     */\n    static URI rootURI(URL url) {","sourceCodeStart":318,"sourceCodeEnd":354,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/core/src/main/java/org/elasticsearch/core/internal/provider/EmbeddedImplClassLoader.java#L318-L354","documentation":"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.","triggerScenarios":"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'.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate the scheme before constructing/using the embedded classloader\nstatic void requireLocalScheme(URI root) {\n    if (!\"file\".equals(root.getScheme()) && !\"jar\".equals(root.getScheme())) {\n        throw new IllegalArgumentException(\"unsupported codebase scheme: \" + root.getScheme());\n    }\n}","typeGuard":"static boolean isSupportedCodebaseScheme(URI uri) {\n    String s = uri.getScheme();\n    return \"file\".equals(s) || \"jar\".equals(s);\n}","tryCatchPattern":"try {\n    return embeddedJarPath(prefixes, rootURI);\n} catch (IOException e) {\n    // log the offending URI and surface; embedded loading does not support remote schemes\n    throw new IllegalStateException(\"cannot load provider from \" + rootURI, e);\n}","preventionTips":["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."],"tags":["classloader","modules","classpath","url","provider","elasticsearch-core","packaging"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}