Flutter CERTIFICATE_VERIFY_FAILED on Android 13/14 but works perfectly on Android 16 (Sectigo CA)

1 day ago 2
ARTICLE AD BOX

I am developing a Flutter application that communicates with a live API server via HTTPS. The API calls work perfectly on an Android 16 device, but when I test the exact same code on devices running Android 13 or Android 14, I get the following SSL Handshake Exception:

HandshakeException: Handshake error in client (OS Error:

CERTIFICATE_VERIFY_FAILED: unable to get local issuer certificate)

Server & SSL Configuration: To ensure the server isn't the issue, I ran a Qualys SSL Labs test on my domain (myworkhub.talbridge.in).

Grade: A-

Chain Issues: None (The intermediate certificates are properly served).

Issuer: Sectigo Public Server Authentication CA DV R36.

Root CA: Sectigo Public Server Authentication Root R46.

My Current Workaround: To keep development moving, I implemented an HttpOverrides class to bypass the certificate check only for my specific domain. This successfully fixes the issue on Android 13 and 14:

class MyHttpOverrides extends HttpOverrides { @override HttpClient createHttpClient(SecurityContext? context) { return super.createHttpClient(context) ..badCertificateCallback = (X509Certificate cert, String host, int port) { // Bypassing only for my specific host to prevent global MITM vulnerabilities if (host == "myworkhub.talbridge.in") { return true; } return false; }; } } void main() async { WidgetsFlutterBinding.ensureInitialized(); HttpOverrides.global = MyHttpOverrides(); runApp(MyApp()); }

My Questions:

Why does Android 16 trust this Sectigo R46 Root CA automatically, while Android 13 and 14 fail to verify the exact same certificate chain?

Is there a secure, recommended way to bundle or trust this specific Root CA inside the Flutter app so I don't have to rely on badCertificateCallback for production?

Any help or guidance on how to properly handle this missing root certificate issue in older Android versions would be highly appreciated.

Read Entire Article