{"record":{"id":"7be9e9f35633c4cb","repo":"kestra-io/kestra","slug":"cannot-process-the-uri-s-scheme-not-supported-7be9e9","errorCode":null,"errorMessage":"Cannot process the URI %s: scheme not supported.","messagePattern":"Cannot process the URI (.+?): scheme not supported\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/io/kestra/core/runners/pebble/functions/ReadFileFunction.java","lineNumber":65,"sourceCode":"    @Override\n    protected Object fileFunction(EvaluationContext context, URI path, String namespace, String tenantId, Map<String, Object> args) throws IOException {\n        return switch (path.getScheme()) {\n            case StorageContext.KESTRA_SCHEME -> {\n                try (InputStream inputStream = storageInterface.get().get(tenantId, namespace, path)) {\n                    yield readContent(inputStream);\n                }\n            }\n            case LocalPath.FILE_SCHEME -> {\n                try (InputStream inputStream = localPathFactory.get().createLocalPath().get(path)) {\n                    yield readContent(inputStream);\n                }\n            }\n            case Namespace.NAMESPACE_FILE_SCHEME -> {\n                try (InputStream inputStream = contentInputStream(path, namespace, tenantId, args)) {\n                    yield readContent(inputStream);\n                }\n            }\n            default -> throw new IllegalArgumentException(SCHEME_NOT_SUPPORTED_ERROR.formatted(path));\n        };\n    }\n\n    // Returns byte[] for binary ION (preserves fidelity for fromIon()), String for everything else\n    private static Object readContent(InputStream inputStream) throws IOException {\n        byte[] bytes = inputStream.readAllBytes();\n        if (IonStreamUtils.isIonBinary(bytes)) {\n            return bytes;\n        }\n        return new String(bytes, StandardCharsets.UTF_8);\n    }\n\n    private InputStream contentInputStream(URI path, String namespace, String tenantId, Map<String, Object> args) throws IOException {\n        Namespace namespaceStorage = namespaceFactory.get().of(tenantId, namespace, storageInterface.get());\n\n        if (args.containsKey(REVISION)) {\n            return namespaceStorage.getFileContent(\n                NamespaceFile.normalize(Path.of(path.getPath())),","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/kestra-io/kestra/blob/823fada9274c4f9c251ea0a516460a4f7d958032/core/src/main/java/io/kestra/core/runners/pebble/functions/ReadFileFunction.java#L47-L83","documentation":"The read() Pebble function accepts a path argument and dispatches on the URI scheme to the correct storage backend. Supported schemes are 'kestra://' (internal storage), 'file://' (local files, requires LocalFiles enabled), and 'nsfile://' (namespace files). Any other scheme (e.g., http://, https://, s3://, ftp://) reaches the default branch and throws IllegalArgumentException, which is caught upstream and re-wrapped as a PebbleException. The same constant is also thrown from AbstractFileFunction when a string path matches the generic URI pattern but is none of the recognized schemes.","triggerScenarios":"Calling {{ read('https://example.com/file.txt') }}, {{ read('s3://bucket/key') }}, or any path with an unknown scheme. Also triggered when a variable that was expected to hold a kestra:// URI or a plain relative path instead contains a fully-qualified URL with an unsupported scheme.","commonSituations":"A flow output URI from an external system (e.g., an HTTP download task) is passed to read() without converting it to internal storage first. Misconfiguring a path variable that accidentally includes an 'http://' or custom scheme prefix. Using read() when you actually need an HTTP fetch or a plugin-specific download.","solutions":["Use a plugin task (e.g., io.kestra.plugin.core.http.Download) to fetch remote URLs into internal storage, then pass the resulting kestra:// URI to read().","For namespace files, use a plain relative path or the 'nsfile://' scheme: {{ read('nsfile:///path/to/file') }}.","For internal storage outputs, pass the raw output URI variable (e.g., {{ outputs.download.uri }}) which is already kestra://.","Check that the path variable does not contain a scheme prefix when you intend a namespace-file relative path."],"exampleFix":"# before — unsupported scheme\n- id: read_remote\n  type: io.kestra.plugin.core.log.Log\n  message: \"{{ read('https://example.com/data.json') }}\"\n\n# after — download to internal storage, then read\n- id: download\n  type: io.kestra.plugin.core.http.Download\n  uri: \"https://example.com/data.json\"\n- id: read_downloaded\n  type: io.kestra.plugin.core.log.Log\n  message: \"{{ read(outputs.download.uri) }}\"","handlingStrategy":"validation","validationCode":"# Before calling read(), verify the path scheme is supported.\n# Supported: kestra://, file:// (if LocalFiles enabled), nsfile://, or plain relative paths.\n{% set supported = path starts with 'kestra://' or path starts with 'nsfile://' or path starts with 'file://' or not path matches '^[a-zA-Z][a-zA-Z0-9+.-]*:.*' %}\n{% if supported %}{{ read(path) }}{% else %}UNSUPPORTED_SCHEME{% endif %}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always verify the path variable holds a kestra:// URI, an nsfile:// URI, or a plain relative path before passing to read().","Download remote URLs with io.kestra.plugin.core.http.Download before reading.","Avoid passing raw external URIs to read(); convert them to internal storage first.","Log the path value before read() during development to catch scheme mismatches early."],"tags":["pebble","read","uri","storage","scheme"],"backgroundTag":null,"analyzedSha":"823fada9274c4f9c251ea0a516460a4f7d958032","analyzedAt":"2026-08-14T06:15:17.947Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}