{"record":{"id":"9bacdaac7956c000","repo":"grpc/grpc-java","slug":"we-can-not-do-tls-handshake-on-this-android-versio","errorCode":null,"errorMessage":"We can not do TLS handshake on this Android version, please install the Google Play Services Dynamic Security Provider to use TLS","messagePattern":"We can not do TLS handshake on this Android version, please install the Google Play Services Dynamic Security Provider to use TLS","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"okhttp/src/main/java/io/grpc/okhttp/OkHttpProtocolNegotiator.java","lineNumber":305,"sourceCode":"            return;\n          }\n        }\n      } catch (IllegalAccessException e) {\n        throw new RuntimeException(e);\n      } catch (InvocationTargetException e) {\n        throw new RuntimeException(e);\n      } catch (InstantiationException e) {\n        throw new RuntimeException(e);\n      }\n\n      Object[] parameters = {Platform.concatLengthPrefixed(protocols)};\n      if (platform.getTlsExtensionType() == TlsExtensionType.ALPN_AND_NPN) {\n        SET_ALPN_PROTOCOLS.invokeWithoutCheckedException(sslSocket, parameters);\n      }\n      if (platform.getTlsExtensionType() != TlsExtensionType.NONE) {\n        SET_NPN_PROTOCOLS.invokeWithoutCheckedException(sslSocket, parameters);\n      } else {\n        throw new RuntimeException(\"We can not do TLS handshake on this Android version, please\"\n            + \" install the Google Play Services Dynamic Security Provider to use TLS\");\n      }\n    }\n\n    @Override\n    public String getSelectedProtocol(SSLSocket socket) {\n      if (GET_APPLICATION_PROTOCOL != null) {\n        try {\n          return (String) GET_APPLICATION_PROTOCOL.invoke(socket);\n        } catch (IllegalAccessException e) {\n          throw new RuntimeException(e);\n        } catch (InvocationTargetException e) {\n          Throwable targetException = e.getTargetException();\n          if (targetException instanceof UnsupportedOperationException) {\n            logger.log(\n                Level.FINER,\n                \"Socket unsupported for getApplicationProtocol, will try old methods\");\n          } else {","sourceCodeStart":287,"sourceCodeEnd":323,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/okhttp/src/main/java/io/grpc/okhttp/OkHttpProtocolNegotiator.java#L287-L323","documentation":"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.","triggerScenarios":"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.","commonSituations":"Android < 4.4 or devices with outdated security patch level, apps not bundling Conscrypt, emulators with old system images.","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)"],"exampleFix":"// before\nOkHttpChannelBuilder.forAddress(host, port).build(); // old Android, no ALPN/NPN\n// after\nProviderInstaller.installIfNeeded(context); // Google Play Services provider\nOkHttpChannelBuilder.forAddress(host, port).build();","handlingStrategy":"fallback","validationCode":"if (Platform.get().getTlsExtensionType() == TlsExtensionType.NONE) { ProviderInstaller.installIfNeeded(context); }","typeGuard":"boolean tlsExtensionsAvailable() { return Platform.get().getTlsExtensionType() != TlsExtensionType.NONE; }","tryCatchPattern":"try { stub.unaryCall(req); } catch (RuntimeException e) { if (e.getMessage().contains(\"Dynamic Security Provider\")) { ProviderInstaller.installIfNeeded(context); retry(); } throw e; }","preventionTips":["Call ProviderInstaller.installIfNeeded at app startup on Android","Bundle conscrypt-android as a fallback provider","Raise minSdkVersion to a level with ALPN/NPN support"],"tags":["grpc","okhttp","android","tls","alpn","security-provider"],"backgroundTag":"unsupported-platform","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}