quarkusio/quarkus · error · IllegalArgumentException

Unsupported provider: ${provider}

Error message

Unsupported provider: ${provider}

What it means

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.

Source

Thrown at extensions/grpc-common/runtime/src/main/java/io/quarkus/grpc/common/runtime/graal/GrpcNettySubstitutions.java:47

    }
}

@TargetClass(className = "io.grpc.netty.GrpcSslContexts")
final class Target_io_grpc_netty_GrpcSslContexts {

    @Substitute
    public static SslContextBuilder configure(SslContextBuilder builder, SslProvider provider) {
        switch (provider) {
            case JDK: {
                Provider jdkProvider = findJdkProvider();
                if (jdkProvider == null) {
                    throw new IllegalArgumentException(
                            "Could not find Jetty NPN/ALPN or Conscrypt as installed JDK providers");
                }
                return configure(builder, jdkProvider);
            }
            default:
                throw new IllegalArgumentException("Unsupported provider: " + provider);
        }
    }

    @Alias
    private static Provider findJdkProvider() {
        return null;
    }

    @Alias
    public static SslContextBuilder configure(SslContextBuilder builder, Provider jdkProvider) {
        return null;
    }

}

@TargetClass(className = "io.grpc.netty.Utils")
final class Target_io_grpc_netty_Utils {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Use SslProvider.JDK in native mode (with Conscrypt/Jetty ALPN present), or
  2. Remove the explicit provider selection and let Quarkus/netty pick a supported native TLS path
  3. Guard provider selection code with RuntimeHints checking image mode

Example fix

// before
GrpcSslContexts.configure(builder, SslProvider.OPENSSL);
// after
GrpcSslContexts.configure(builder, SslProvider.JDK); // in native image
Defensive patterns

Strategy: validation

Validate before calling

SslProvider provider = /* chosen */ SslProvider.JDK;
boolean nativeImage = System.getProperty("org.graalvm.nativeimage.imagecode") != null;
if (nativeImage && provider != SslProvider.JDK) {
    LOG.warn("Only JDK provider is substituted in native image");
}

Try / catch

try {
    return GrpcSslContexts.configure(builder, provider);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Unsupported provider")) {
        return GrpcSslContexts.configure(builder, SslProvider.JDK);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling the substituted GrpcSslContexts.configure(builder, provider) with a provider other than SslProvider.JDK — e.g. SslProvider.OPENSSL — in a native image build/run.

Common situations: Explicitly selecting OpenSSL in code that is later compiled to native; a library internally choosing a non-JDK provider; version change altering provider defaults.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/f25502b900433f85. Report an issue: GitHub.