I’m running into a strange TLS/HTTPS issue in my Flutter project and can’t figure out why it only happens inside Flutter/Dart.
I have a backend API hosted at:
https://my-backend/api/v1If I call the endpoint from Postman or curl, it works correctly:
curl -X GET \'https://my-backend/api/v1/users/123'However, when I try to call the exact same URL from Flutter (or even a simple Dart test), I get this error:
HandshakeException: Handshake error in client (OS Error:WRONG_VERSION_NUMBER(tls_record.cc:127))Code that generates the error
test('should fetch user by id', () async { final testBaseUri = BaseUri( baseUrl: 'https://my-backend/api/v1', ); final userResult = await users_res.getUserById('123', testBaseUri, ); expect(userResult, isNotNull);});getUserById:
final url = baseUri.getEndpoint('/users/$id');final defaultHeaders = {'Accept': 'application/json','Content-Type': 'application/json',};final response = await backendClient.get(url, headers: defaultHeaders);if (response.statusCode >= 200 && response.statusCode < 300) { return User.fromJson(json.decode(response.body));} else { throw Exception('Failed to get user: ${response.reasonPhrase}');}HTTP client:
final backendClient = http.Client();The generated URL:
https://my-backend/api/v1/users/123So it’s definitely calling the correct route.
What I’ve already checked/tried• Verified that the backend does serve HTTPS (confirmed via curl/Postman).• Verified the generated URL is correct.
• Tried using http.get(Uri.parse(...)) directly — same error.• Tried from both Flutter tests and a raw Dart script — still the same error.• Tried disabling proxy usage via:
HttpClient()..findProxy = (_) => 'DIRECT';• Tried an insecure client with badCertificateCallback (referenced from here )— the handshake error still happens.• No custom HttpOverrides.global in my code.• Tested on different networks.
The backend is reachable from everything except Dart/Flutter’s HTTP client, which fails immediately during TLS handshake before even sending a request.
My question
What could cause Dart/Flutter’s HttpClient to fail the TLS handshake with WRONG_VERSION_NUMBER while Postman and curl work fine with the exact same HTTPS URL?
Is there something environment-specific about Flutter/Dart TLS behavior that I may be missing (proxy, DNS, certificate chain, ALPN, etc.)?
Any guidance on how to debug this further is appreciated.