cURL Error Codes: Complete Reference & Fixes
When a cURL command fails, it returns a numeric exit code that tells you exactly what went wrong. Understanding these cURL error codes is essential for debugging HTTP requests, proxy connections, and automation scripts. This guide covers every common cURL error with causes and fixes.
How cURL Error Codes Work
cURL returns exit code 0 on success and a non-zero code on failure. You can check the exit code with $? in bash:
curl https://example.com
echo $? # 0 = success
curl https://nonexistent.example.com
echo $? # 6 = could not resolve host
Most Common cURL Errors
Exit Code 6: Could Not Resolve Host
The DNS lookup for the hostname failed.
# Error
curl https://nonexistent.example.com
curl: (6) Could not resolve host: nonexistent.example.com
Fix: Check DNS
nslookup nonexistent.example.com
dig nonexistent.example.com
Try different DNS server
curl --dns-servers 8.8.8.8 https://example.com
Exit Code 7: Failed to Connect
TCP connection to the server was refused or failed.
# Error
curl http://localhost:9999
curl: (7) Failed to connect to localhost port 9999
Fix: Check if the service is running
ss -tlnp | grep 9999
netstat -tlnp | grep 9999
Check firewall
sudo iptables -L -n
sudo ufw status
Exit Code 28: Operation Timed Out
The request exceeded the timeout limit.
# Error (default timeout is very long)
curl --max-time 5 https://slow-server.example.com
curl: (28) Operation timed out after 5001 milliseconds
Fix: Increase timeout
curl --max-time 60 https://slow-server.example.com
curl --connect-timeout 10 --max-time 60 https://slow-server.example.com
Exit Code 35: SSL Connect Error
The SSL/TLS handshake failed.
# Error
curl https://bad-ssl.example.com
curl: (35) SSL connect error
Debug
curl -v https://bad-ssl.example.com
Fix: Try specific TLS version
curl --tlsv1.2 https://bad-ssl.example.com
Skip verification (dev only)
curl -k https://bad-ssl.example.com
Exit Code 51: SSL Peer Certificate Error
The server’s SSL certificate verification failed.
# Error
curl https://self-signed.example.com
curl: (51) SSL: certificate subject name does not match target host name
Fix: Specify CA cert
curl --cacert /path/to/ca.pem https://self-signed.example.com
Exit Code 52: Empty Reply from Server
The server returned an empty response.
# Error
curl http://example.com:8080
curl: (52) Empty reply from server
Debug
curl -v http://example.com:8080
Fix: Check if server is sending a response
telnet example.com 8080
Exit Code 56: Network Receive Error
Failure while receiving network data.
# Error
curl https://example.com
curl: (56) Recv failure: Connection reset by peer
Common causes: server dropped connection, firewall interference, proxy issues
Fix: Try with different network or proxy
curl -x http://proxy.example.com:8080 https://example.com
Exit Code 60: SSL Certificate Problem
The SSL certificate could not be verified against the CA bundle.
# Error
curl https://example.com
curl: (60) SSL certificate problem: unable to get local issuer certificate
Fix: Update CA bundle
sudo apt install ca-certificates
sudo update-ca-certificates
Or specify CA bundle
curl --cacert /etc/ssl/certs/ca-certificates.crt https://example.com
Skip verification (NOT recommended for production)
curl -k https://example.com
Complete Error Code Reference
| Code | Name | Description |
|---|---|---|
| 1 | Unsupported protocol | URL uses an unsupported protocol |
| 2 | Failed to initialize | Internal cURL initialization error |
| 3 | URL malformat | Invalid URL syntax |
| 5 | Could not resolve proxy | DNS lookup for proxy hostname failed |
| 6 | Could not resolve host | DNS lookup for target hostname failed |
| 7 | Failed to connect | TCP connection refused or failed |
| 8 | Weird server reply | Server sent an unexpected response |
| 9 | Remote access denied | Access to the resource was denied |
| 18 | Partial file | Only partial data was transferred |
| 22 | HTTP returned error | Server returned a 4xx/5xx error (with --fail) |
| 23 | Write error | Could not write data to local filesystem |
| 26 | Read error | Could not read a local file for upload |
| 27 | Out of memory | Memory allocation failed |
| 28 | Timeout | Operation exceeded the timeout limit |
| 33 | Range error | Server does not support byte ranges |
| 35 | SSL connect error | TLS/SSL handshake failure |
| 47 | Too many redirects | Redirect limit exceeded |
| 51 | SSL cert error | Peer certificate verification failed |
| 52 | Empty reply | Server sent nothing back |
| 55 | Send failure | Failed to send network data |
| 56 | Recv failure | Failed to receive network data |
| 58 | Local SSL cert error | Problem with the local client certificate |
| 60 | CA cert problem | Cannot verify server certificate against CA |
| 67 | Login denied | Server denied the login credentials |
| 77 | CA cert read error | Could not read the CA cert file |
| 92 | HTTP/2 error | Problem with the HTTP/2 framing layer |
| 97 | Proxy handshake error | HTTPS proxy handshake failure |
Debugging cURL Errors
Verbose Output
# Show request/response details
curl -v https://example.com
Even more detail (includes SSL negotiation)
curl -vv https://example.com
Write debug trace to file
curl --trace debug.txt https://example.com
curl --trace-ascii debug.txt https://example.com
Timing Information
curl -w "\
DNS Lookup: %{time_namelookup}s\n\
TCP Connect: %{time_connect}s\n\
TLS Setup: %{time_appconnect}s\n\
First Byte: %{time_starttransfer}s\n\
Total: %{time_total}s\n\
HTTP Code: %{http_code}\n" \
-o /dev/null -s https://example.com
Handling cURL Errors in Scripts
#!/bin/bash
URL="https://example.com"
MAX_RETRIES=3
RETRY_DELAY=5
for i in $(seq 1 $MAX_RETRIES); do
response=$(curl -s -o /dev/null -w "%{http_code}" --max-time 30 "$URL")
exit_code=$?
if [ $exit_code -eq 0 ] && [ "$response" = "200" ]; then
echo "Success!"
break
fi
echo "Attempt $i failed (exit code: $exit_code, HTTP: $response)"
if [ $i -lt $MAX_RETRIES ]; then
echo "Retrying in ${RETRY_DELAY}s..."
sleep $RETRY_DELAY
fi
done
import subprocess
def curl_with_error_handling(url):
result = subprocess.run(
["curl", "-s", "-o", "/dev/null", "-w", "%{http_code}", "--max-time", "30", url],
capture_output=True, text=True
)
if result.returncode != 0:
error_messages = {
6: "Could not resolve host",
7: "Connection refused",
28: "Timeout",
35: "SSL error",
60: "Certificate error",
}
error = error_messages.get(result.returncode, f"Unknown error {result.returncode}")
print(f"cURL error: {error}")
return None
return result.stdout.strip()
FAQ
How do I find the cURL error code after a command?
Run echo $? immediately after the cURL command. Exit code 0 means success; any other number indicates an error.
What is the difference between cURL error codes and HTTP status codes?
cURL error codes indicate transport-level issues (DNS, TCP, SSL). HTTP status codes (200, 404, 500) are application-level responses. You can get a cURL success (exit code 0) but still receive an HTTP error (like 404).
How do I make cURL treat HTTP errors as failures?
Use the --fail flag: curl --fail https://example.com/404. This causes cURL to return exit code 22 for HTTP 4xx/5xx responses instead of exit code 0.
Can I get both the cURL error code and the HTTP status code?
Yes: curl -s -o /dev/null -w "%{http_code}" https://example.com; echo "Exit: $?" shows the HTTP code followed by the cURL exit code.