curl Error Codes: Complete Reference
When a curl command fails, it returns a numeric exit code (also called curl error code) that identifies the type of error. You can check the curl exit code by running echo $? immediately after the curl command (or $LASTEXITCODE in PowerShell). Exit code 0 means success; any other number indicates a specific problem — from DNS resolution failures and connection timeouts to SSL certificate issues. This page is a complete reference of the most common curl error codes with explanations, causes, and fixes. If you're working with curl commands in your code, paste them into curl2code to convert to your programming language of choice.
Quick Reference Table
Success. The operation completed without any errors.
Unsupported protocol. The URL uses a protocol that curl was not built with support for.
Malformed URL. The URL syntax is invalid or could not be parsed.
Could not resolve proxy. The specified proxy hostname could not be resolved.
DNS lookup failed — the hostname could not be resolved to an IP address.
TCP connection failed — server is down, port is blocked, or firewall is rejecting connections.
Partial file. The transfer was interrupted and only part of the file was received.
Server returned an HTTP error (4xx/5xx) and --fail flag was used.
Write error. curl failed to write received data to disk (permission denied or disk full).
The operation exceeded the maximum allowed time (DNS, connect, or transfer).
SSL/TLS handshake failed — protocol version or cipher suite mismatch.
Could not read file. A local file referenced in the request could not be opened or read.
Empty reply from server. The server closed the connection without sending any data.
Connection was reset — the server dropped the connection during data transfer.
SSL certificate verification failed — expired, self-signed, or CA bundle is outdated.
SSL CA cert problem. Could not read or parse the specified CA certificate file.
HTTP/2 stream error. An HTTP/2 protocol-level stream error occurred during the transfer.
Error 6: Could Not Resolve Host
- What it means
- Your terminal shows
curl: (6) Could not resolve host. curl could not resolve the hostname to an IP address — the DNS lookup failed before any connection was attempted. - Causes
- The most common causes are: a typo in the hostname (e.g.,
curl https://apiexample.cominstead ofapi.example.com), DNS server issues (your configured DNS is down or unreachable), no network connection (Wi-Fi disconnected, VPN not connected), or the domain genuinely does not exist. - How to fix
- First, verify the URL is correct. Then test DNS resolution directly:
nslookup api.example.comordig api.example.com. If DNS fails, try a different DNS server:curl --dns-servers 8.8.8.8 https://api.example.com. Check your/etc/resolv.confor network settings. If behind a corporate VPN, ensure the internal DNS can resolve the host.
$ curl https://api.exmple.com/usersError 7: Failed to Connect
- What it means
- Your terminal shows
curl: (7) Failed to connect to host port: Connection refused. curl resolved the hostname but could not establish a TCP connection to the server — the connection was actively refused or timed out at the TCP level. - Causes
- Common causes include: the server is down or not running, a firewall is blocking the port (check both local and server-side firewalls), the port is wrong (e.g., the service runs on 8080 but you're connecting to 443), or the server's listen backlog is full under heavy load.
- How to fix
- Verify the server is running:
ping api.example.comandtelnet api.example.com 443. Check if the correct port is open:nmap -p 443 api.example.com. Disable local firewall temporarily to test. If using Docker, ensure the container port is published. Try with verbose mode:curl -v https://api.example.comto see exactly where the connection fails.
$ curl https://localhost:8080/apiError 22: HTTP Returned Error
- What it means
- Your terminal shows
curl: (22) The requested URL returned error. The server returned an HTTP error status code (4xx or 5xx) and curl was invoked with-for--fail, which tells curl to treat HTTP errors as failures. - Causes
- The error is triggered by HTTP status codes like 400 (Bad Request), 401 (Unauthorized), 403 (Forbidden), 404 (Not Found), or 500 (Internal Server Error) — but only when
--failis used. Without--fail, curl exits with code 0 even on HTTP errors. Common causes: wrong URL, missing authentication, insufficient permissions, or server-side bugs. - How to fix
- Run curl without
--failto see the full response body — it often contains the actual error message. Check the HTTP status code:curl -w "%{http_code}" -o /dev/null -s URL. For 401/403: verify your auth token or API key. For 404: double-check the URL path. For 500: the issue is server-side.
$ curl --fail https://api.example.com/nonexistentError 28: Operation Timed Out
- What it means
- Your terminal shows
curl: (28) Operation timed outorcurl: (28) Connection timed out. The operation took longer than the allowed time. This is the most common curl error — it can occur during DNS resolution, TCP connection, SSL handshake, or data transfer. - Causes
- Typical causes include: slow or overloaded server not responding in time, network congestion or packet loss, firewall silently dropping packets (no rejection, just silence), overly strict timeout values set with
--connect-timeoutor--max-time, or a proxy misconfiguration causing delays. - How to fix
- Increase the timeout:
curl --connect-timeout 30 --max-time 120 URL. Use verbose mode to see where it hangs:curl -v URL. Test network latency:ping api.example.comandtraceroute api.example.com. If behind a proxy, try bypassing it:curl --noproxy '*' URL. For large file transfers, consider using--retry 3with--retry-delay 5.
$ curl --connect-timeout 5 https://slow-api.example.com/dataError 35: SSL Connect Error
- What it means
- Your terminal shows
curl: (35) SSL connect error. The SSL/TLS handshake failed — curl could not establish a secure connection with the server. - Causes
- Common causes: TLS version mismatch (server requires TLS 1.3 but your curl only supports up to TLS 1.2), cipher suite incompatibility, server SSL misconfiguration (expired cert presented during handshake, incomplete chain), the server doesn't actually support HTTPS on the given port, or a proxy or firewall is intercepting the SSL connection (MITM).
- How to fix
- Force a specific TLS version:
curl --tlsv1.2 URLorcurl --tlsv1.3 URL. Check what the server supports:openssl s_client -connect api.example.com:443. Update curl and OpenSSL to the latest versions. If the server uses a self-signed cert, this is usually error 60 instead — error 35 typically indicates a protocol-level handshake failure.
$ curl https://legacy-server.example.com/apiError 56: Recv Failure — Connection Was Reset
- What it means
- Your terminal shows
curl: (56) Recv failure: Connection reset by peer. The connection was established successfully, but data reception failed — the server closed or reset the connection unexpectedly during the transfer. - Causes
- This often happens when: the server crashes or restarts mid-transfer, a load balancer or proxy drops the connection (idle timeout, request too large), a firewall terminates long-lived connections, the server has a keep-alive timeout shorter than expected, or there's a network disruption between client and server.
- How to fix
- Try the request again — transient network issues are the most common cause. Use verbose mode:
curl -v URLto see the exact point of failure. If the error happens during large uploads, try chunked transfer:curl -H "Transfer-Encoding: chunked" URL. For Git operations showingRPC failed; curl 56, increase the buffer:git config http.postBuffer 524288000.
$ curl https://api.example.com/large-downloadError 60: SSL Certificate Problem
- What it means
- Your terminal shows
curl: (60) SSL certificate problem: unable to get local issuer certificate. curl could not verify the server's SSL certificate against its CA (Certificate Authority) bundle. The TLS handshake completed at the protocol level, but certificate validation failed. - Causes
- Most common causes: the server uses a self-signed certificate, the certificate has expired, the certificate chain is incomplete (missing intermediate certificates), curl's CA bundle is outdated (common on older systems or in Docker containers), or the certificate's Common Name / SAN doesn't match the requested hostname.
- How to fix
- Update the CA bundle:
curl --cacert /path/to/cacert.pem URL. Download an updated bundle from https://curl.se/ca/cacert.pem. To diagnose:openssl s_client -connect api.example.com:443 -showcerts. For self-signed certs in development, usecurl -k URL(never in production — it disables all certificate verification). In Docker, installca-certificatespackage.
$ curl https://self-signed.example.com/apiOther Error Codes
Success. The operation completed without any errors.
Unsupported protocol. The URL uses a protocol that curl was not built with support for.
Malformed URL. The URL syntax is invalid or could not be parsed.
Could not resolve proxy. The specified proxy hostname could not be resolved.
Partial file. The transfer was interrupted and only part of the file was received.
Write error. curl failed to write received data to disk (permission denied or disk full).
Could not read file. A local file referenced in the request could not be opened or read.
Empty reply from server. The server closed the connection without sending any data.
SSL CA cert problem. Could not read or parse the specified CA certificate file.
HTTP/2 stream error. An HTTP/2 protocol-level stream error occurred during the transfer.
How to Debug curl Errors
When curl fails, these three flags help you quickly identify the root cause — from DNS resolution to SSL handshake to response payload.
- 1
Enable verbose output
Run
curl -v URLto see the full request/response cycle: DNS resolution, TCP connection, TLS handshake, request headers sent, and response headers received. This is the single most useful debugging flag. - 2
Check the HTTP status code
Run
curl -o /dev/null -s -w "%{http_code}" URLto get just the HTTP status code (200, 404, 500, etc.) without the response body. Useful for quick health checks and scripting. - 3
Show errors silently
Run
curl -sS URLto suppress the progress bar (-s) but still show errors (-S). Perfect for scripts where you want clean output but need to catch failures.
Frequently Asked Questions
How to check the curl exit code?
After running a curl command, the exit code is stored in the shell's special variable. In Bash/Zsh, run echo $? immediately after the curl command. In PowerShell, use $LASTEXITCODE. In scripts, you can check it with a conditional: if curl -sf URL; then echo "OK"; else echo "Failed with code $?"; fi. Exit code 0 means success; any other number indicates an error. To see both the HTTP status code and the curl exit code, combine curl -w "%{http_code}" -o /dev/null -s URL; echo "Exit: $?". Note that curl's exit code is different from the HTTP status code — curl returns 0 even for HTTP 404 unless you use the --fail flag.
How to fix curl error 28 (operation timed out)?
Error 28 means the request exceeded the maximum allowed time. First, increase the timeout: curl --connect-timeout 30 --max-time 120 URL. The --connect-timeout limits the TCP connection phase, while --max-time limits the entire operation. Next, diagnose the bottleneck with curl -v URL — the verbose output shows exactly where curl gets stuck (DNS, connect, TLS, or transfer). Common fixes: check your network connection and DNS settings, verify the server is responding (ping and telnet), bypass proxies with --noproxy '*', and for large downloads add --retry 3 --retry-delay 5 for automatic retries.
How to fix curl SSL certificate errors (error 60)?
Error 60 means curl cannot verify the server's SSL certificate. The fix depends on the cause. For an outdated CA bundle: download a fresh one from https://curl.se/ca/cacert.pem and use curl --cacert /path/to/cacert.pem URL. For Docker containers: install the ca-certificates package (apt-get install ca-certificates). For self-signed certificates in development: use curl -k URL to skip verification — but never use -k in production as it disables all certificate checking. To diagnose: run openssl s_client -connect host:443 -showcerts to inspect the certificate chain. If the certificate has expired or the hostname doesn't match, the issue is on the server side.
What does curl error 7 (failed to connect) mean?
Error 7 means curl resolved the hostname to an IP address but could not establish a TCP connection. The server actively refused the connection or the connection attempt timed out at the network level. Common causes: the service is not running on the target host (check with systemctl status or docker ps), a firewall is blocking the port (test with telnet host port), you're using the wrong port (e.g., 80 instead of 443, or 8080 for a dev server), or the server's listen backlog is full under heavy load. To debug: use curl -v URL and look for "Connected to" or "Connection refused" in the output.