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

0CURLE_OK

Success. The operation completed without any errors.

1CURLE_UNSUPPORTED_PROTOCOL

Unsupported protocol. The URL uses a protocol that curl was not built with support for.

3CURLE_URL_MALFORMAT

Malformed URL. The URL syntax is invalid or could not be parsed.

5CURLE_COULDNT_RESOLVE_PROXY

Could not resolve proxy. The specified proxy hostname could not be resolved.

6CURLE_COULDNT_RESOLVE_HOST

DNS lookup failed — the hostname could not be resolved to an IP address.

7CURLE_COULDNT_CONNECT

TCP connection failed — server is down, port is blocked, or firewall is rejecting connections.

18CURLE_PARTIAL_FILE

Partial file. The transfer was interrupted and only part of the file was received.

22CURLE_HTTP_RETURNED_ERROR

Server returned an HTTP error (4xx/5xx) and --fail flag was used.

23CURLE_WRITE_ERROR

Write error. curl failed to write received data to disk (permission denied or disk full).

28CURLE_OPERATION_TIMEDOUT

The operation exceeded the maximum allowed time (DNS, connect, or transfer).

35CURLE_SSL_CONNECT_ERROR

SSL/TLS handshake failed — protocol version or cipher suite mismatch.

37CURLE_FILE_COULDNT_READ_FILE

Could not read file. A local file referenced in the request could not be opened or read.

52CURLE_GOT_NOTHING

Empty reply from server. The server closed the connection without sending any data.

56CURLE_RECV_ERROR

Connection was reset — the server dropped the connection during data transfer.

60CURLE_SSL_CACERT

SSL certificate verification failed — expired, self-signed, or CA bundle is outdated.

77CURLE_SSL_CACERT_BADFILE

SSL CA cert problem. Could not read or parse the specified CA certificate file.

92CURLE_HTTP2_STREAM

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.com instead of api.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.com or dig 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.conf or network settings. If behind a corporate VPN, ensure the internal DNS can resolve the host.
$ curl https://api.exmple.com/users

Error 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.com and telnet 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.com to see exactly where the connection fails.
$ curl https://localhost:8080/api

Error 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 -f or --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 --fail is 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 --fail to 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/nonexistent

Error 28: Operation Timed Out

What it means
Your terminal shows curl: (28) Operation timed out or curl: (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-timeout or --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.com and traceroute api.example.com. If behind a proxy, try bypassing it: curl --noproxy '*' URL. For large file transfers, consider using --retry 3 with --retry-delay 5.
$ curl --connect-timeout 5 https://slow-api.example.com/data

Error 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 URL or curl --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/api

Error 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 URL to 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 showing RPC failed; curl 56, increase the buffer: git config http.postBuffer 524288000.
$ curl https://api.example.com/large-download

Error 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, use curl -k URL (never in production — it disables all certificate verification). In Docker, install ca-certificates package.
$ curl https://self-signed.example.com/api

Other Error Codes

0CURLE_OK

Success. The operation completed without any errors.

1CURLE_UNSUPPORTED_PROTOCOL

Unsupported protocol. The URL uses a protocol that curl was not built with support for.

3CURLE_URL_MALFORMAT

Malformed URL. The URL syntax is invalid or could not be parsed.

5CURLE_COULDNT_RESOLVE_PROXY

Could not resolve proxy. The specified proxy hostname could not be resolved.

18CURLE_PARTIAL_FILE

Partial file. The transfer was interrupted and only part of the file was received.

23CURLE_WRITE_ERROR

Write error. curl failed to write received data to disk (permission denied or disk full).

37CURLE_FILE_COULDNT_READ_FILE

Could not read file. A local file referenced in the request could not be opened or read.

52CURLE_GOT_NOTHING

Empty reply from server. The server closed the connection without sending any data.

77CURLE_SSL_CACERT_BADFILE

SSL CA cert problem. Could not read or parse the specified CA certificate file.

92CURLE_HTTP2_STREAM

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. 1

    Enable verbose output

    Run curl -v URL to 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. 2

    Check the HTTP status code

    Run curl -o /dev/null -s -w "%{http_code}" URL to get just the HTTP status code (200, 404, 500, etc.) without the response body. Useful for quick health checks and scripting.

  3. 3

    Show errors silently

    Run curl -sS URL to 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.