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.
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)
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: ${provider}
- Provider %s could not be instantiated %s
- OCSP is not supported with this SslProvider:
- Cannot parse version from output: ${stringOutput}
- Not Implemented in native mode
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/821d022cfe2c6ae7.
Report an issue: GitHub.