Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

isadma's avatar

Handshake error on flutter with Laravel 7

I use Laravel 7 for backend, Nginx on the server, and flutter for apps.

I installed an SSL layer for my server by using Let's encrypt and Certbot. Before SSL everything was fine, it was working. But after installing SSL I got this error on flutter:

HandshakeExceiption: Handshake error in client (OS error: TLSV1_ALERT_PROTOCOL_VERSION(tls_record.cc:587))

It is my flutter request code:

import 'package:package_info/package_info.dart';
import 'dart:io';
import 'package:dio/dio.dart';
import './home.dart';
import './auth.dart';

String token;

class RootProvider {
  static Dio http = Dio();
  static final baseUrl = "https://my_domain.com/api";
  static String locale = '';

  static Future<void> setRequestHeaders() async {
    token = await AuthProvider.getToken();
    String _locale = await HomeProvider.getLocale();
    locale = _locale == 'en' ? 'tm' : _locale;
    PackageInfo packageInfo = await PackageInfo.fromPlatform();
    String platform = "";

    if (Platform.isAndroid) {
      platform = "android";
    } else if (Platform.isIOS) {
      platform = "ios";
    }

    var headers = {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'Language': _locale == 'en' ? 'tm' : _locale,
      'Version': packageInfo?.version,
      'Platform': platform,
    };
    if (token != null) headers['Authorization'] = "Bearer $token";
    http.options.baseUrl = baseUrl;
    http.options.headers = headers;
  }

  static init() async {
    await setRequestHeaders();

    http.interceptors.add(
      InterceptorsWrapper(
        onRequest: (RequestOptions options) {
          print('Making request to ${options.method} ${options.uri}');
        },
        onResponse: (Response response) {
          // if response successful then return data
          if (response.data['success'] == true && response.data['success']) {
            return http.resolve(response);
          }

          return http.reject(response.data['message']);
        },
        onError: (DioError e) async {
          return http.reject(e);
        },
      ),
    );
  }
}

It is my Nginx conf:

server {
    listen 80;
    listen [::]:80;

    server_name my_domain.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name my_domain.com;
    root /var/www/my_domain/public;

        ssl_certificate /etc/letsencrypt/live/my_domain.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/my_domain.com/privkey.pem;

        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

        add_header X-Frame-Options "SAMEORIGIN";
        add_header X-XSS-Protection "1; mode=block";
        add_header X-Content-Type-Options "nosniff";

        index index.php index.html index.htm index.nginx-debian.html;

    charset utf-8;

    location / {
            try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    }

    location ~ /\.ht {
            deny all;
    }

    location ~ /.well-known {
            allow all;
    }
}

Note: I tried to send a request by Axios on javascript and I got a success response. It works on Axios and Javascript. It is only not working on flutter.

Please, help me to find problem. Thank you in advance

0 likes
4 replies
bobbybouwmann's avatar

Mmh, are you sure the SSL certificate is valid? Most of the time this is happening because the app can't connect to the server because the certificate is not setup correctly.

Can you try to do a request using http instead of https and see if that works?

Maybe you can find some more info here: https://stackoverflow.com/a/62100490

isadma's avatar

Thank you for your reply. How can I check that SSL certificate is valid or not?

isadma's avatar

I checked these stackoverflow link before. It didn't help.

boyjarv's avatar
boyjarv
Best Answer
Level 7

I am also having this issue after I set my port number as 80

String url = "https://choosapi.test:80/api/auth/login";

    final response = await http.post(
      Uri.parse(url),
      headers: <String, String>{
        'Accept': 'application/json',
        'Content-Type': 'application/json; charset=UTF-8',
      },
      body: jsonEncode(loginRequestModel)
    );

Please or to participate in this conversation.