Why Nginx Resets HTTPS Curl Requests and How to Fix It
This article walks through a real‑world Nginx HTTPS troubleshooting case where curl requests are reset, detailing packet captures, configuration tweaks, SSL session cache settings, and a comprehensive list of common Nginx error messages to help engineers quickly locate and resolve similar issues.
Problem Description
After deploying an HTTPS certificate, browsers accessed the site normally, but curl requests were reset.
Investigation Steps
1. Curl to the same domain over HTTP returned normally, confirming port 80 connectivity.
2. Curl to other HTTPS domains on the same server succeeded, confirming port 443 connectivity.
The certificate was valid and not expired.
3. Modified the SSL cipher suite to a more compatible list, but the issue persisted.
"ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4"4. Captured traffic with tcpdump and analyzed in Wireshark. The reset occurred after the first ACK of data transmission.
5. Adjusted Nginx client buffer settings:
client_header_buffer_size 64k;
large_client_header_buffers 4 64k;
client_body_buffer_size 20m;
keepalive_timeout 120;The problem remained.
6. Switched from an RSA certificate to an ECC certificate. Curl then reported:
curl: (35) Cannot communicate securely with peer: no common encryption algorithm(s).On RedHat/CentOS, curl uses the NSS library, which disables ECC by default. Specifying compatible ciphers is required.
curl --ciphers ecdhe_rsa_aes_128_gcm_sha_256 ...Even after specifying ciphers, the reset persisted.
Breakthrough
Adding the ssl_session_cache directive resolved the issue. The author compared configurations and found that enabling a shared cache improved the behavior.
Explanation of ssl_session_cache options:
off : disables session caching.
none : disables storage but may indicate reuse.
builtin : uses OpenSSL’s built‑in cache per worker (default ~20,480 sessions).
shared : shared cache across workers; size specified in bytes (e.g., 1m ≈ 4,000 sessions).
Recommendation: use the shared option for better performance.
Additional Nginx Error Log Reference
Common error messages and their meanings:
upstream prematurely closed connection : upstream closed before response; can be ignored.
recv() failed (104: Connection reset by peer) : possible server overload or client abort.
(111: Connection refused) while connecting to upstream : upstream unavailable.
(111: Connection refused) while reading response header from upstream : upstream died after connection.
(110: Connection timed out) while connecting to upstream : timeout during connection.
(110: Connection timed out) while reading upstream : timeout reading data.
SSL_do_handshake() failed : SSL handshake failure.
ngx_slab_alloc() failed: no memory in SSL session shared cache : session cache too small.
could not add new SSL session to the session cache while SSL handshaking : session cache exhausted.
For packet capture, tcpdump works, but Wireshark provides detailed analysis.
Efficient Ops
This public account is maintained by Xiaotianguo and friends, regularly publishing widely-read original technical articles. We focus on operations transformation and accompany you throughout your operations career, growing together happily.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
