quarkusio/quarkus · error · IllegalArgumentException
Could not find Jetty NPN/ALPN or Conscrypt as installed JDK…
Error message
Could not find Jetty NPN/ALPN or Conscrypt as installed JDK providers
What it means
This is a GraalVM native-image substitution for Netty's GrpcSslContexts.configure. In native mode Netty's JDK-provider lookup cannot find Jetty NPN/ALPN or Conscrypt, so the substituted findJdkProvider returns null and the code throws IllegalArgumentException. TLS over gRPC with SslProvider.JDK cannot be set up in the native image.
Solutions
- Add Conscrypt as a dependency and register it for reflection/native so it is found as a JDK provider
- Configure gRPC TLS to use the OpenSSL provider instead of JDK
- Avoid the Netty gRPC JDK SSL path in native mode (e.g. use Quarkus-managed TLS config)
Example fix
// before
GrpcSslContexts.forClient().trustManager(ca).build(); // defaults to JDK provider in native
// after
GrpcSslContexts.configure(GrpcSslContexts.forClient().trustManager(ca),
SslProvider.OPENSSL).build(); Defensive patterns
Strategy: fallback
Validate before calling
Provider p = Security.getProvider("Conscrypt");
if (p == null && isNativeImage()) {
LOG.warn("No ALPN/Conscrypt JDK provider; use OpenSSL provider for native TLS");
} Try / catch
try {
GrpcSslContexts.configure(builder, SslProvider.JDK);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Jetty NPN/ALPN")) {
return GrpcSslContexts.configure(builder, SslProvider.OPENSSL);
}
throw e;
} Prevention
- Add Conscrypt dependency for native TLS
- Test TLS gRPC in native mode, not only JVM mode
- Prefer Quarkus-managed TLS config over manual Netty SSL setup
When it happens
Trigger: Building/running a native-image application that uses gRPC over TLS with the JDK SSL provider, when neither Conscrypt nor Jetty ALPN is available as a JDK provider in the image.
Common situations: Native build of a TLS-enabled gRPC client/server without adding Conscrypt; upgrading to native image where JDK ALPN bootclasspath hooks no longer exist.
Related errors
- Unsupported provider
- OCSP is not supported with this SslProvider:
- Provider could not be instantiated
- Authentication strategy 'dialog' is not supported in GraalVM
- requires SSL support but it is disabled. You probably have…
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/821d022cfe2c6ae7.
Report an issue: GitHub.
Appendix: source
Thrown at extensions/grpc-common/runtime/src/main/java/io/quarkus/grpc/common/runtime/graal/GrpcNettySubstitutions.java:41
@Substitute
static void logSslEngineDetails(Level level, ChannelHandlerContext ctx, String msg, Throwable t) {
Logger log = Logger.getLogger("io.grpc.netty.ProtocolNegotiators");
if (log.isLoggable(level)) {
log.log(level, msg + "\nNo SSLEngine details available!", t);
}
}
}
@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;
}View on GitHub (pinned to e1c734241f)