grpc/grpc-java · error · RuntimeException
TLS ALPN negotiation failed with protocols
Error message
TLS ALPN negotiation failed with protocols: ${protocols} What it means
OkHttpProtocolNegotiator.negotiate forces the SSL handshake and then reads the ALPN/ NPN negotiated protocol; if the socket reports no selected protocol it throws RuntimeException naming the configured protocols. This means TLS succeeded but the peers did not agree on an application protocol (e.g. h2).
Solutions
- Ensure the server supports HTTP/2 with ALPN and advertises h2
- Upgrade to a JDK with ALPN support (8u251+ or 11+), or install Conscrypt as the security provider
- Verify no intermediary (LB/proxy) strips ALPN extension
- If using custom SSLSocketFactory/sslSocket override, make sure it doesn't disable ALPN
Example fix
// before
SSLSocket socket = factory.createSocket(...); // JDK without ALPN
// after
Security.insertProviderAt(Conscrypt.newProvider(), 1);
SSLContext ctx = SSLContext.getInstance("TLS", "Conscrypt"); Defensive patterns
Strategy: fallback
Validate before calling
// detect JDK ALPN availability boolean alpnOk = Platform.get().getTlsExtensionType() != TlsExtensionType.NONE;
Try / catch
try { stub.unaryCall(req); } catch (RuntimeException e) { if (e.getMessage().contains("ALPN negotiation failed")) { installConscryptAndRetry(); } throw e; } Prevention
- Use JDK 11+ or JDK 8u251+ which ship ALPN
- Install Conscrypt on Android/legacy JVMs
- Confirm server advertises h2 via ALPN (openssl s_client -alpn h2)
When it happens
Trigger: Server does not support ALPN or advertises no protocol gRPC requires (h2), client protocol list mismatched, or Android/JDK version lacking ALPN support so getSelectedProtocol returns null.
Common situations: Old JDK 7/8 without ALPN support, servers without HTTP/2 enabled, load balancers stripping ALPN, Android versions needing Google Play Services provider.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Expected NPN/ALPN
- We can not do TLS handshake on this Android version, please…
- Could not find Jetty NPN/ALPN or Conscrypt as installed JDK…
- Could not find TLS ALPN provider; no working…
- EOF trying to read bytes
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/6c8ea51a098576eb.
Report an issue: GitHub.
Appendix: source
Thrown at okhttp/src/main/java/io/grpc/okhttp/OkHttpProtocolNegotiator.java:106
/**
* Start and wait until the negotiation is done, returns the negotiated protocol.
*
* @throws IOException if an IO error was encountered during the handshake.
* @throws RuntimeException if the negotiation completed, but no protocol was selected.
*/
public String negotiate(
SSLSocket sslSocket, String hostname, @Nullable List<Protocol> protocols) throws IOException {
if (protocols != null) {
configureTlsExtensions(sslSocket, hostname, protocols);
}
try {
// Force handshake.
sslSocket.startHandshake();
String negotiatedProtocol = getSelectedProtocol(sslSocket);
if (negotiatedProtocol == null) {
throw new RuntimeException("TLS ALPN negotiation failed with protocols: " + protocols);
}
return negotiatedProtocol;
} finally {
platform.afterHandshake(sslSocket);
}
}
/** Configure TLS extensions. */
protected void configureTlsExtensions(
SSLSocket sslSocket, String hostname, List<Protocol> protocols) {
platform.configureTlsExtensions(sslSocket, hostname, protocols);
}
/** Returns the negotiated protocol, or null if no protocol was negotiated. */
public String getSelectedProtocol(SSLSocket socket) {
return platform.getSelectedProtocol(socket);
}
View on GitHub (pinned to 64daddc1f3)