grpc/grpc-java · critical · RuntimeException
We can not do TLS handshake on this Android version, please
Error message
We can not do TLS handshake on this Android version, please install the Google Play Services Dynamic Security Provider to use TLS
What it means
AndroidApiNegotiator (older Android path) throws this when the platform supports neither ALPN nor NPN TLS extensions (TlsExtensionType.NONE), so protocol negotiation cannot occur. The message instructs installing the Google Play Services Dynamic Security Provider.
Source
Thrown at okhttp/src/main/java/io/grpc/okhttp/OkHttpProtocolNegotiator.java:305
return;
}
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
}
Object[] parameters = {Platform.concatLengthPrefixed(protocols)};
if (platform.getTlsExtensionType() == TlsExtensionType.ALPN_AND_NPN) {
SET_ALPN_PROTOCOLS.invokeWithoutCheckedException(sslSocket, parameters);
}
if (platform.getTlsExtensionType() != TlsExtensionType.NONE) {
SET_NPN_PROTOCOLS.invokeWithoutCheckedException(sslSocket, parameters);
} else {
throw new RuntimeException("We can not do TLS handshake on this Android version, please"
+ " install the Google Play Services Dynamic Security Provider to use TLS");
}
}
@Override
public String getSelectedProtocol(SSLSocket socket) {
if (GET_APPLICATION_PROTOCOL != null) {
try {
return (String) GET_APPLICATION_PROTOCOL.invoke(socket);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
Throwable targetException = e.getTargetException();
if (targetException instanceof UnsupportedOperationException) {
logger.log(
Level.FINER,
"Socket unsupported for getApplicationProtocol, will try old methods");
} else {View on GitHub (pinned to 64daddc1f3)
Solutions
- Add the Google Play Services Security Provider and call ProviderInstaller.installIfNeeded(context) before creating the channel
- Bundle Conscrypt for Android (org.conscrypt:conscrypt-android) and register it as the first security provider
- Raise minSdkVersion / require a device with TLS extension support
- Use plaintext only in controlled/test environments (not recommended for production)
Example fix
// before OkHttpChannelBuilder.forAddress(host, port).build(); // old Android, no ALPN/NPN // after ProviderInstaller.installIfNeeded(context); // Google Play Services provider OkHttpChannelBuilder.forAddress(host, port).build();
Defensive patterns
Strategy: fallback
Validate before calling
if (Platform.get().getTlsExtensionType() == TlsExtensionType.NONE) { ProviderInstaller.installIfNeeded(context); } Type guard
boolean tlsExtensionsAvailable() { return Platform.get().getTlsExtensionType() != TlsExtensionType.NONE; } Try / catch
try { stub.unaryCall(req); } catch (RuntimeException e) { if (e.getMessage().contains("Dynamic Security Provider")) { ProviderInstaller.installIfNeeded(context); retry(); } throw e; } Prevention
- Call ProviderInstaller.installIfNeeded at app startup on Android
- Bundle conscrypt-android as a fallback provider
- Raise minSdkVersion to a level with ALPN/NPN support
When it happens
Trigger: Running gRPC-OkHttp with TLS on an old Android version whose default Conscrypt/SSLSocket lacks both ALPN and NPN, then performing a TLS handshake via configureTlsExtensions.
Common situations: Android < 4.4 or devices with outdated security patch level, apps not bundling Conscrypt, emulators with old system images.
Understand the failure class
Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- TLS Provider failure
- TLS ALPN negotiation failed with protocols: ${protocols}
- Unable to load OkHttpChannelProvider
- TLS not supported in BinderServer
- Could not find Jetty NPN/ALPN or Conscrypt as installed JDK
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/9bacdaac7956c000.
Report an issue: GitHub.