{"record":{"id":"82d0a8abc1e17360","repo":"quarkusio/quarkus","slug":"unable-to-read-resourcename-from-path","errorCode":null,"errorMessage":"Unable to read ${resourceName} from ${path}","messagePattern":"Unable to read (.+?) from (.+?)","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":null,"severity":"error","filePath":"extensions/grpc/runtime/src/main/java/io/quarkus/grpc/runtime/supports/Channels.java","lineNumber":268,"sourceCode":"\n    }\n\n    private static Buffer bufferFor(Path path, String resourceName) throws IOException {\n        try (InputStream stream = streamFor(path, resourceName)) {\n            return Buffer.buffer(stream.readAllBytes());\n        }\n    }\n\n    private static InputStream streamFor(Path path, String resourceName) {\n        final InputStream resource = Thread.currentThread().getContextClassLoader()\n                .getResourceAsStream(ClassPathUtils.toResourceName(path));\n        if (resource != null) {\n            return resource;\n        } else {\n            try {\n                return Files.newInputStream(path);\n            } catch (IOException e) {\n                throw new UncheckedIOException(\"Unable to read \" + resourceName + \" from \" + path, e);\n            }\n        }\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public static Channel retrieveChannel(String name, Set<String> perClientInterceptors) {\n        ClientInterceptorStorage clientInterceptorStorage = Arc.container().instance(ClientInterceptorStorage.class).get();\n        Annotation[] qualifiers = new Annotation[perClientInterceptors.size() + 1];\n        int idx = 0;\n        qualifiers[idx++] = GrpcClient.Literal.of(name);\n        for (String interceptor : perClientInterceptors) {\n            qualifiers[idx++] = RegisterClientInterceptor.Literal\n                    .of((Class<? extends ClientInterceptor>) clientInterceptorStorage.getPerClientInterceptor(interceptor));\n        }\n        InstanceHandle<Channel> instance = Arc.container().instance(Channel.class, qualifiers);\n        if (!instance.isAvailable()) {\n            throw new IllegalStateException(\"Unable to retrieve the gRPC Channel \" + name);\n        }","sourceCodeStart":250,"sourceCodeEnd":286,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/grpc/runtime/src/main/java/io/quarkus/grpc/runtime/supports/Channels.java#L250-L286","documentation":"Channels.streamFor resolves a resource by name (classloader resource) and falls back to opening it as a file path. When neither the classloader resource exists nor Files.newInputStream(path) succeeds (file missing, unreadable, is a directory), the IOException is wrapped into an UncheckedIOException with the message 'Unable to read <resourceName> from <path>'. This is used e.g. for loading certificate/authority material when building gRPC channels.","triggerScenarios":"Configuring a gRPC client (e.g. trust-store / key-store path or SSL material) with a path/resource name that neither matches a classpath resource nor an existing readable file, so streamFor('name', 'path') fails on both branches during channel creation.","commonSituations":"Typo in the certificate path; file present in dev but not packaged into the native image or container; relative path resolved against a different working directory at runtime; file permissions deny read for the running user.","solutions":["Verify the path exists and is readable at runtime (ls/stat the exact path the process sees, including working directory for relative paths).","Put the file under src/main/resources so it ships as a classpath resource, and reference it by resource name only.","For native images/container builds, include the file (quarkus.native.resources.includes or volume mount) and use an absolute path.","Check file permissions for the user running the Quarkus process."],"exampleFix":"// before\nquarkus.grpc.clients.hello.trust-store.pem.paths=./ca.pem  // not packaged\n\n// after\n# copy ca.pem to src/main/resources/certs/ca.pem\nquarkus.grpc.clients.hello.trust-store.pem.paths=certs/ca.pem","handlingStrategy":"validation","validationCode":"// ensure the trust/key material is resolvable before configuring the client\nString path = \"certs/ca.pem\";\nboolean asResource = Thread.currentThread().getContextClassLoader().getResource(path) != null\n    || Channels.class.getClassLoader().getResource(path) != null;\nboolean asFile = java.nio.file.Files.isRegularFile(java.nio.file.Path.of(path))\n    && java.nio.file.Files.isReadable(java.nio.file.Path.of(path));\nif (!asResource && !asFile) {\n    throw new IllegalStateException(\"Resource/file not found or unreadable: \" + path);\n}","typeGuard":null,"tryCatchPattern":"try {\n    channel = Channels.createChannel(\"hello\", interceptors);\n} catch (UncheckedIOException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Unable to read\")) {\n        throw new ConfigurationException(\"Package the resource into the app (src/main/resources) or fix the path: \" + e.getMessage(), e);\n    }\n    throw e;\n}","preventionTips":["Ship certificate material as classpath resources under src/main/resources.","For native images, register files via quarkus.native.resources.includes.","Use absolute paths when loading from the filesystem and verify readability as the runtime user."],"tags":["io","resources","grpc","classpath"],"backgroundTag":"resource-not-found","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}