Network

curl Exit Code Reference

A complete reference for curl command exit codes — meanings, common causes, and fixes for developers debugging CI/CD pipelines and shell scripts. Includes a lookup tool — enter a code number to see details instantly.

curl Exit Code Reference Table
Code Constant Name Meaning Common Causes
Connection / Initialization Errors
1 CURLE_UNSUPPORTED_PROTOCOL Indicates that curl does not support the protocol specified in the URL. Occurs when using a curl binary built without that protocol enabled (e.g. gopher, ldap), or a typo in the URL scheme.
2 CURLE_FAILED_INIT Indicates that curl's internal initialization failed. A rare low-level initialization failure, typically caused by insufficient memory or an abnormal environment.
3 CURLE_URL_MALFORMAT Indicates that the specified URL is malformed and curl cannot parse it. Occurs when the URL is missing its scheme (e.g. http://) or contains invalid characters.
5 CURLE_COULDNT_RESOLVE_PROXY Indicates that curl failed to resolve the hostname of the specified proxy server. Caused by a typo in the hostname passed to --proxy, or a DNS failure specific to the proxy.
6 CURLE_COULDNT_RESOLVE_HOST Indicates that curl failed to resolve (DNS) the hostname of the destination server. Typically caused by a typo in the domain name, a DNS server outage, or running in an offline environment.
7 CURLE_COULDNT_CONNECT Indicates that the hostname was resolved, but curl failed to establish a TCP connection to the server. Occurs due to an incorrect port number, a firewall blocking the connection, or the server being down.
8 CURLE_WEIRD_SERVER_REPLY Indicates that curl received an unexpected response from the server that it could not interpret. Common when an FTP server returns a non-standard response, or when curl accidentally connects to a server speaking a different protocol.
9 CURLE_REMOTE_ACCESS_DENIED Indicates that curl connected to the server but access was denied. Occurs due to insufficient permissions for an FTP directory, or when the server enforces an IP restriction.
Data Transfer Errors
18 CURLE_PARTIAL_FILE Indicates that the transfer was interrupted before completion, so only part of the file was received. Occurs due to a brief network interruption, or when the server closes the connection earlier than the announced Content-Length.
23 CURLE_WRITE_ERROR Indicates that curl failed to write data to the local disk or the destination callback. Occurs when the disk is full, or curl lacks write permission for the output file.
26 CURLE_READ_ERROR Indicates that curl failed to read the local file to be uploaded. Occurs when the file specified with -T/--upload-file does not exist, or curl lacks read permission for it.
52 CURLE_GOT_NOTHING Indicates that curl connected to the server but received no response at all. Typically caused by the server process crashing mid-request, or a misconfiguration that returns an empty response.
55 CURLE_SEND_ERROR Indicates that curl failed to send data over the network. Occurs when the remote side disconnects immediately after the connection is established, or due to a local network interface issue.
56 CURLE_RECV_ERROR Indicates that curl failed to receive data from the network. Commonly seen when the remote side unexpectedly resets the connection mid-transfer (Connection reset by peer).
63 CURLE_FILESIZE_EXCEEDED Indicates that the file size exceeded the limit set with --max-filesize. Occurs when the response turns out larger than expected and hits the safety limit you configured.
78 CURLE_REMOTE_FILE_NOT_FOUND Indicates that the specified file does not exist on the remote server (e.g. FTP). Occurs due to a typo in the FTP path, or when the target file has already been deleted or moved.
SSL/TLS Certificate Errors
35 CURLE_SSL_CONNECT_ERROR Indicates that a problem occurred during the SSL/TLS handshake, preventing the connection from being established. Commonly caused by a mismatch between the TLS versions or cipher suites supported by the server and the client.
51 CURLE_PEER_FAILED_VERIFICATION Indicates that verification of the server certificate failed (e.g. the certificate does not match the hostname). Occurs when accessing a self-signed certificate, or when the certificate's Common Name/SAN differs from the destination hostname.
58 CURLE_SSL_CERTPROBLEM Indicates a problem with the locally specified client certificate. Typically caused by an invalid format in the certificate file passed with --cert, or an incorrect passphrase.
60 CURLE_SSL_CACERT Indicates that curl could not verify the CA certificate chain used to validate the server certificate. Occurs when the CA certificate bundle is outdated, or a self-signed CA (such as a corporate proxy's) is not registered in the trust store. -k/--insecure is a workaround, but it is not recommended for production use.
HTTP / Authentication Errors
22 CURLE_HTTP_RETURNED_ERROR Indicates that, with the -f/--fail option specified, the HTTP response returned an error status of 400 or higher. Triggered intentionally in CI/CD scripts that use curl -f so that an API error status is detected as a failure.
67 CURLE_LOGIN_DENIED Indicates that the login (authentication) to the server was rejected. Typically caused by an incorrect username or password, or an account lockout on protocols such as FTP/SMTP.
Other
27 CURLE_OUT_OF_MEMORY Indicates that curl failed to allocate memory during execution. A rare situation, such as attempting to handle a huge file on a memory-constrained system.
28 CURLE_OPERATION_TIMEDOUT Indicates that the operation did not complete within the time limit set with --connect-timeout/--max-time, etc. One of the most frequent errors seen in CI, caused by a slow server response, network latency, or a timeout value set too short.
47 CURLE_TOO_MANY_REDIRECTS Indicates that the number of redirects exceeded the limit set with --max-redirs. Occurs with a redirect loop (301/302 redirecting circularly), or a legitimate redirect chain longer than the default limit (50).

Tips

  • You can check the exit code immediately with $? (Bash) or %errorlevel% (Windows). In shell scripts, branching like curl ... || echo "failed with $?" is a handy pattern.
  • 28 (timeout) and 7 (connection failed) are often confused, but 28 occurs when the response is slow after a connection is made, while 7 occurs when the TCP connection itself could never be established.
  • If you get 60 (CA certificate error), don't just work around it with -k/--insecure — first check whether your CA certificate bundle (ca-certificates) is up to date. Using -k routinely in production increases the risk of man-in-the-middle attacks.
  • 22 (HTTP error) only occurs when you add the -f/--fail option. Without it, curl returns exit code 0 (success) even for a 404 or 500 response, so always add -f if you want CI to detect failures.

FAQ

Right after running the curl command, check it with echo $? in Bash/Zsh, echo %errorlevel% in the Windows Command Prompt, or $LASTEXITCODE in PowerShell.

First review your --connect-timeout and --max-time settings and extend them if needed. If the server is consistently slow to respond, also check server load and the network path (proxies, VPNs, etc.).

No, they are different. HTTP status codes (such as 404 or 500) are protocol-level responses returned by the server, while curl exit codes indicate the result of the curl command itself (connection failure, timeout, etc.). By default curl treats HTTP errors as exit code 0 (success), so be careful not to confuse the two.

Add the curl -f (--fail) option so that curl returns exit code 22 whenever the HTTP response is 400 or higher. Without it, successfully fetching an error page still results in exit code 0.

6 (COULDNT_RESOLVE_HOST) is an error at the DNS stage, where the hostname could not be resolved to an IP address. 7 (COULDNT_CONNECT) is an error where name resolution succeeded but the TCP connection to that IP address could not be established.
ツールくん

Side Note — The curl Exit Code System

curl is a command-line tool whose development began in 1996 by Daniel Stenberg, originally under the name "httpget." Today curl ships by default on virtually every Linux distribution, macOS, and Windows 10 and later, making it one of the most fundamental tools for web developers.

The exit code system maps directly onto libcurl's internal error enum, CURLcode, and is defined as a sequential numbering starting with `CURLE_OK` (success, exit code 0). Gaps in the numbering exist because some error codes were deprecated or merged during development.

Interestingly, curl's exit codes form their own independent system, separate from the general POSIX convention (0 = success, 1 = general error). This means that when handling exit codes across multiple tools in a shell script, you need to check each tool's manual individually to understand its meaning.