The Problem
Seeing SSL_ERROR_SYSCALL usually means the connection died unexpectedly. Unlike a certificate mismatch where the server says "I don't trust you," this error happens when the connection is slammed shut before the encryption handshake even finishes. The underlying system call—usually read() or write()—received a Reset (RST) packet or an EOF when it expected data.
Your terminal will typically spit out this frustrating line:
curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to example.com:443
Common Causes
- Proxy Interference: A corporate proxy might kill the connection because it doesn't recognize the SSL protocol or it's waiting for authentication that never came.
- Middleboxes and DPI: Deep Packet Inspection (DPI) firewalls often drop encrypted traffic they can't decrypt or inspect.
- MTU Bottlenecks: If you are on a VPN, your packets might be too large for the tunnel, leading to silent drops.
- IPv6 Hang-ups:
curlmight try to reach a server via IPv6 while your proxy only understands IPv4.
Step-by-Step Fixes
1. Force IPv4
Proxies often trip over IPv6 addresses. Forcing curl to stay on IPv4 is the quickest way to rule out DNS and routing mismatches.
curl -4 -v https://example.com
2. Sanitize Proxy Environment Variables
Misconfigured environment variables are a frequent culprit. A missing http:// prefix or a trailing slash in your proxy string can break the handshake. Check your current settings first:
env | grep -i proxy
If they look off, reset them using the standard format. Avoid adding trailing slashes to the port number:
export http_proxy="http://proxy.example.com:8080"
export https_proxy="http://proxy.example.com:8080"
To bypass local environment issues entirely, pass the proxy directly into the command:
curl -x http://proxy.example.com:8080 -v https://example.com
3. Adjust the MTU (Maximum Transmission Unit)
Network packets aren't one-size-fits-all. Standard Ethernet uses a 1500-byte MTU, but VPN headers (like those in OpenVPN or Cisco AnyConnect) shrink the available space. When a packet exceeds the limit, it's often dropped, triggering a syscall error. Try lowering your MTU to 1400 or 1300 to see if the connection stabilizes.
# Find your active interface (e.g., eth0, en0, or wlan0)
ip link show
# Temporarily drop the MTU to 1400
sudo ip link set dev eth0 mtu 1400
Run your curl command again. If it works, you've confirmed a network fragmentation issue.
4. Downgrade to TLS 1.2
Legacy hardware and older "security appliances" often choke on TLS 1.3. Forcing curl to use the older, more widely compatible TLS 1.2 can bypass these picky middleboxes.
curl --tls-max 1.2 -v https://example.com
5. Update curl and OpenSSL
Old versions of OpenSSL (like the 1.0.2 series) lack support for modern cipher suites. Check your version with curl --version. If you are running a version from several years ago, it's time to pull the latest binaries.
# For Ubuntu/Debian users
sudo apt update && sudo apt install curl openssl
# For RHEL/CentOS users
sudo yum update curl openssl
Verification
Use the verbose flag (-v) to inspect the handshake. You want to see the certificate exchange finish. A healthy connection ends with a line like this:
* SSL connection using TLSv1.3 / AEAD-AES256-GCM-SHA384
* ALPN, server accepted to use h2
If you see that "SSL connection using" line, you've successfully bypassed the syscall error.
Tips and Prevention
Network-level errors usually stem from misconfigured subnets or overly aggressive firewall rules. When I'm debugging why a proxy rejects specific traffic, I use a Subnet Calculator to double-check my network boundaries. It ensures the IP ranges allowed in the firewall actually align with the CIDR blocks used by the proxy.
One final trick: if you're stuck behind a very strict firewall, use --trace-ascii output.txt. This generates a full hex dump of the connection. You can hand this file to your network admin to show exactly which packet (often the Client Hello) is getting blocked.

