kestra-io/kestra · error · IllegalArgumentException

Scheme not supported: {}

Error message

Scheme not supported: {}

What it means

Thrown by URIFetcher.fetchInputStream()'s switch on uri.getScheme() when the scheme passed the constructor's SUPPORTED_SCHEMES check at deserialization but the runtime RunContext does not provide a reader for it, OR more commonly when a URIFetcher is built bypassing the constructor (e.g., from an already-open URI). The default branch is a defensive fallback for any scheme not matching kestra/file/namespace. Unlike error 29, this fires at fetch time, not construction time, and the message omits the supported list.

Source

Thrown at core/src/main/java/io/kestra/core/models/property/URIFetcher.java:97

     *
     * @throws IOException if an IO error occurs
     * @throws SecurityException if the URI points to a path that is not allowed
     */
    public InputStream fetch(RunContext runContext) throws IOException {
        if (uri == null) {
            return InputStream.nullInputStream();
        }

        // we need to first check the protocol, then create one reader by protocol
        return switch (uri.getScheme()) {
            case StorageContext.KESTRA_SCHEME -> runContext.storage().getFile(uri);
            case LocalPath.FILE_SCHEME -> runContext.localPath().get(uri);
            case Namespace.NAMESPACE_FILE_SCHEME -> {
                var namespace = uri.getAuthority() == null ? runContext.storage().namespace() : runContext.storage().namespace(uri.getAuthority());
                var nsFileUri = namespace.get(Path.of(uri.getPath())).uri();
                yield runContext.storage().getFile(nsFileUri);
            }
            default -> throw new IllegalArgumentException("Scheme not supported: " + uri.getScheme());
        };
    }
}

View on GitHub (pinned to 823fada927)

Solutions

  1. Always construct URIFetcher via new URIFetcher(uri) or URIFetcher.of(uri) so the constructor validates the scheme.
  2. Confirm the scheme exactly matches one of: kestra, file, namespace (lowercase).
  3. If adding a new scheme, update BOTH SUPPORTED_SCHEMES and the switch statement.

Example fix

// before (bypasses constructor guard)
URIFetcher f = new URIFetcher(URI.create("ftp://h/data")); // may pass if ftp were in list but not switch
f.fetchInputStream(ctx); // default -> throw

// after
new URIFetcher(URI.create("kestra:///data")).fetchInputStream(ctx);
Defensive patterns

Strategy: try-catch

Validate before calling

String scheme = uri.getScheme();
if (!Set.of(StorageContext.KESTRA_SCHEME, LocalPath.FILE_SCHEME, Namespace.NAMESPACE_FILE_SCHEME).contains(scheme)) {
    throw new IllegalArgumentException("Scheme not supported: " + scheme);
}

Try / catch

try {
    fetcher.fetchInputStream(runContext);
} catch (IllegalArgumentException e) {
    log.error("Unsupported scheme at fetch time: {}", e.getMessage());
    throw e;
}

Prevention

When it happens

Trigger: A URIFetcher instance is constructed via a path that skips the scheme validation, then fetchInputStream is called; a custom scheme is injected at runtime; the scheme string differs in case or whitespace from the expected constants.

Common situations: Reflection or test code builds a URIFetcher directly; a serialized URIFetcher round-trips through a format that drops the constructor guard; future scheme additions create an inconsistency between SUPPORTED_SCHEMES and the switch branches.

Related errors


AI-assisted analysis of kestra-io/kestra@823fada927 (2026-08-14). Data as JSON: /api/errors/6e5b009b3fb516f8. Report an issue: GitHub.