I'm trying to configure HTTPS for nginx on Ubuntu 16.04. I've already set it up with listen 443 ssl statements, and told it where to find the certificate and private key files. After that I restarted the server with sudo service nginx restart.

Now when I curl https://my_ip_address, I get the following message:

curl: (35) gnutls_handshake() failed: Handshake failed

I've checked the two log files I know about, /var/log/nginx/access.log and /var/log/nginx/error.log; but it doesn't show any trace of anything from the request.

My question: Does anything get logged when the SSL handshake fails? If so where? In general, how to I troubleshoot problems like this, where there is an error in the SSL protocol before the HTTP request is sent to, or extracted by the server?

EDIT: I got it to work by removing the following lines from my config:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver valid=300s;
resolver_timeout 5s;

Update: The ssl_ecdh_curve secp384r1; line seemed to be causing the problem. Without it, everything works fine, but with it, the SSL handshake fails. Curiously, the error message is that there is "no shared cipher". I'm not sure what it does, so I just removed it. I also removed the ssl_stapling stuff because I don't know what it is for, and it was creating its own error messages

  • Perhaps a more verbose log setting would work. See nginx core module error_log. However, there may be something else wrong with your config revealed with a simple sudo nginx -t or post the relevant portions of the config in your question for more help.
    – Paul
    Sep 19, 2016 at 21:24
  • 1
    I forgot to mention it is generally a good idea to check /var/log/syslog as you may identify other problems, though not necessarily related to this one.
    – Paul
    Sep 19, 2016 at 21:34
  • error_log was already set to warn, and I changed it to alert, but still nothing. Could the error be happening in openssl before the request reaches nginx? Sep 19, 2016 at 22:04
  • and nothing's showing up in my syslog, except for a bunch of UFW blocks that seem to be unrelated Sep 19, 2016 at 22:06
  • 1
    My understanding is that to increase verbosity, you would go in the other direction. For example, debug would be most verbose. For me to guess what is going on, I would need to see the relevant parts of the config. Others may be able to diagnose without it, but I'm not quite that experienced.
    – Paul
    Sep 19, 2016 at 22:08

3 Answers 3


As @Paul said, the solution was to raise the log level. I changed a line in my nginx.conf file, so it now reads as follows:

error_log  /var/log/nginx/error.log debug;

And now that the log level is higher, it logs ssl handshake errors:

2016/09/19 22:38:08 [info] 10114#10114: *2 SSL_do_handshake() failed (SSL: error:1408A0C1:SSL routines:ssl3_get_client_hello:no shared cipher) while SSL handshaking, client:, server:
  • 5
    As shown by the [info] heading, a log level of info would be sufficient, and would be a lot less noisy than debug. Sep 19, 2016 at 22:59
  • @MichaelHampton for some reason my log (basically identical to the one in this post) differs in that it is being logged only from [debug] and not [info]. So for some it might be better to just start with the most verbose logging.
    – Marc
    Jun 19, 2018 at 20:53

Actually you have used the option ssl_ecdh_curve to configure Diffie Hellman key exchange in Nginx but you have not provided a parameter file. Therefore you have to use the option ssl_dhparam and must create a file with openssl.

Create file:

openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096

Use file and above Diffie Hellman configuration in Nginx:

ssl_dhparam                     /etc/ssl/certs/dhparam.pem;
ssl_ecdh_curve                  secp384r1;
  • I accepted my own answer because it answers the original question, but still gave you +1 for pointing this out. Just to note, I actually did have an ssl_dhparam in the config file but somehow it didn't end up in the code I posted. Oct 13, 2016 at 23:00
  • If you want to finish work today, use the command: openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 2048 May 25, 2020 at 7:43
  • This is actually wrong: ssl_dhparams are required for DHE ciphers (TLS_DHE_RSA_....) which are very different from ECDHE ciphers that use the curve from ssl_ecdh_curve. Neither one of those settings requires the other. Nowadays, adding ssl_dhparam to nginx to support DHE ciphers is only advisable if one wants to support older (IE11 on Win 7 apparantly) or special client configs. ECDHE Ciphers are widely supported and faster. (github.com/mozilla/server-side-tls/issues/268)
    – zapl
    Dec 17, 2021 at 19:00

You can check you nginx server config , there is a config line is : ssl_ciphers, the default value is : ssl_ciphers HIGH:!aNULL:!MD5; (http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ciphers), but sometimes is not expect, in my case , nginx-ingress-controller default is less then default config, and the nginx debug log show error is :no shared cipher. when I add some ciphers in config file and reload nginx , the promeble was reloved.And you can reference this config template: https://mozilla.github.io/server-side-tls/ssl-config-generator/

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .