grpc/grpc-java · error · IllegalArgumentException
${jdkProvider} selected, but Java 9+ ALPN unavailable
Error message
${jdkProvider} selected, but Java 9+ ALPN unavailable What it means
For JDK providers like IBM JSSE, OpenJSSE, or Bouncy Castle JSSE, gRPC relies exclusively on Java 9+ built-in ALPN. If isJava9AlpnAvailable() is false (running on Java 8 or a JVM without ALPN API), configure() throws this IllegalArgumentException.
Source
Thrown at netty/src/main/java/io/grpc/netty/GrpcSslContexts.java:218
if (SUN_PROVIDER_NAME.equals(jdkProvider.getName())) {
// Jetty ALPN/NPN only supports one of NPN or ALPN
if (JettyTlsUtil.isJettyAlpnConfigured()) {
apc = ALPN;
} else if (JettyTlsUtil.isJettyNpnConfigured()) {
apc = NPN;
} else if (JettyTlsUtil.isJava9AlpnAvailable()) {
apc = ALPN;
} else {
throw new IllegalArgumentException(
jdkProvider.getName() + " selected, but Java 9+ and Jetty NPN/ALPN unavailable");
}
} else if (IBM_PROVIDER_NAME.equals(jdkProvider.getName())
|| OPENJSSE_PROVIDER_NAME.equals(jdkProvider.getName())
|| BCJSSE_PROVIDER_NAME.equals(jdkProvider.getName())) {
if (JettyTlsUtil.isJava9AlpnAvailable()) {
apc = ALPN;
} else {
throw new IllegalArgumentException(
jdkProvider.getName() + " selected, but Java 9+ ALPN unavailable");
}
} else if (ConscryptLoader.isConscrypt(jdkProvider)) {
apc = ALPN;
// TODO: Conscrypt triggers failures in the TrustManager.
// https://github.com/grpc/grpc-java/issues/7765
builder.protocols("TLSv1.2");
} else {
throw new IllegalArgumentException("Unknown provider; can't configure: " + jdkProvider);
}
return builder
.sslProvider(SslProvider.JDK)
.ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE)
.applicationProtocolConfig(apc)
.sslContextProvider(jdkProvider)
.endpointIdentificationAlgorithm(DEFAULT_ENDPOINT_IDENTIFICATION_ALGORITHM);
}
View on GitHub (pinned to 64daddc1f3)
Solutions
- Upgrade to Java 9+ (11/17 LTS recommended) where ALPN is built in
- Switch to netty-tcnative with SslProvider.OPENSSL which supplies its own ALPN
- Use Conscrypt as the JDK provider instead
- Remove the custom JSSE provider so gRPC's default provider resolution applies
Example fix
// before Security.addProvider(new BouncyCastleJsseProvider()); GrpcSslContexts.configure(builder, SslProvider.JDK); // after GrpcSslContexts.configure(builder, SslProvider.OPENSSL); // with netty-tcnative-boringssl-static
Defensive patterns
Strategy: validation
Validate before calling
if (!JettyTlsUtil.isJava9AlpnAvailable()) { /* cannot use IBM/OpenJSSE/BCJSSE providers with gRPC */ } Type guard
boolean canUseJsseProvider(Provider p) { return JettyTlsUtil.isJava9AlpnAvailable() || ConscryptLoader.isConscrypt(p); } Try / catch
try { return GrpcSslContexts.configure(b, jdkProvider); } catch (IllegalArgumentException e) { return GrpcSslContexts.configure(b, SslProvider.OPENSSL); } Prevention
- Upgrade to Java 11/17 for built-in ALPN
- Prefer netty-tcnative or Conscrypt over vendor JSSE providers
- Test TLS handshake during CI on the target JVM
When it happens
Trigger: configure(builder, jdkProvider) where the provider name matches IBM_PROVIDER_NAME, OPENJSSE_PROVIDER_NAME, or BCJSSE_PROVIDER_NAME and Java 9 ALPN API is not present.
Common situations: Running on IBM JDK 8 with IBMJSSE; using openjsse or BouncyCastle JSSE on Java 8; enterprise environments pinned to these providers on legacy JVMs.
Understand the failure class
Background: "X is not installed. Please install it with pip install Y": missing optional dependency errors — ImportError/ValueError raised when a library's optional extra was never installed — this error's family across 22 libraries.
Related errors
- Could not find Jetty NPN/ALPN or Conscrypt as installed JDK
- ${jdkProvider} selected, but Java 9+ and Jetty NPN/ALPN unav
- Unknown provider; can't configure: ${jdkProvider}
- Could not find TLS ALPN provider; no working netty-tcnative,
- TLS ALPN negotiation failed with protocols: ${protocols}
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/44d519a216efd3bb.
Report an issue: GitHub.