{"record":{"id":"f25502b900433f85","repo":"quarkusio/quarkus","slug":"unsupported-provider-provider","errorCode":null,"errorMessage":"Unsupported provider: ${provider}","messagePattern":"Unsupported provider: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/grpc-common/runtime/src/main/java/io/quarkus/grpc/common/runtime/graal/GrpcNettySubstitutions.java","lineNumber":47,"sourceCode":"    }\n}\n\n@TargetClass(className = \"io.grpc.netty.GrpcSslContexts\")\nfinal class Target_io_grpc_netty_GrpcSslContexts {\n\n    @Substitute\n    public static SslContextBuilder configure(SslContextBuilder builder, SslProvider provider) {\n        switch (provider) {\n            case JDK: {\n                Provider jdkProvider = findJdkProvider();\n                if (jdkProvider == null) {\n                    throw new IllegalArgumentException(\n                            \"Could not find Jetty NPN/ALPN or Conscrypt as installed JDK providers\");\n                }\n                return configure(builder, jdkProvider);\n            }\n            default:\n                throw new IllegalArgumentException(\"Unsupported provider: \" + provider);\n        }\n    }\n\n    @Alias\n    private static Provider findJdkProvider() {\n        return null;\n    }\n\n    @Alias\n    public static SslContextBuilder configure(SslContextBuilder builder, Provider jdkProvider) {\n        return null;\n    }\n\n}\n\n@TargetClass(className = \"io.grpc.netty.Utils\")\nfinal class Target_io_grpc_netty_Utils {\n","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/grpc-common/runtime/src/main/java/io/quarkus/grpc/common/runtime/graal/GrpcNettySubstitutions.java#L29-L65","documentation":"The GraalVM native substitution GrpcNettySubstitutions.configure(builder, provider) only supports SslProvider.JDK (delegating to a found JDK provider). Any other provider value falls into the default branch and throws IllegalArgumentException naming the unsupported provider.","triggerScenarios":"Calling the substituted GrpcSslContexts.configure(builder, provider) with a provider other than SslProvider.JDK — e.g. SslProvider.OPENSSL — in a native image build/run.","commonSituations":"Explicitly selecting OpenSSL in code that is later compiled to native; a library internally choosing a non-JDK provider; version change altering provider defaults.","solutions":["Use SslProvider.JDK in native mode (with Conscrypt/Jetty ALPN present), or","Remove the explicit provider selection and let Quarkus/netty pick a supported native TLS path","Guard provider selection code with RuntimeHints checking image mode"],"exampleFix":"// before\nGrpcSslContexts.configure(builder, SslProvider.OPENSSL);\n// after\nGrpcSslContexts.configure(builder, SslProvider.JDK); // in native image","handlingStrategy":"validation","validationCode":"SslProvider provider = /* chosen */ SslProvider.JDK;\nboolean nativeImage = System.getProperty(\"org.graalvm.nativeimage.imagecode\") != null;\nif (nativeImage && provider != SslProvider.JDK) {\n    LOG.warn(\"Only JDK provider is substituted in native image\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    return GrpcSslContexts.configure(builder, provider);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Unsupported provider\")) {\n        return GrpcSslContexts.configure(builder, SslProvider.JDK);\n    }\n    throw e;\n}","preventionTips":["Only force SslProvider.JDK in native builds","Avoid hard-coding OpenSSL in shared code paths","Verify provider choice in native smoke tests"],"tags":["grpc","netty","native-image","ssl","graalvm"],"backgroundTag":"unsupported-provider-in-native","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"}