curl Exit Codes Reference: Look Up Any Return Code (1-99) & Fix
curl exit codes and return codes reference, 1-99. Look up any code — including 22, 3, 28, 52 — and get its meaning, common causes, and the fix. Built as a fast alternative to the official docs for CI/CD, cron, and shell script debugging.
| 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). |
What Is a curl Exit Code?
A curl exit code is the number curl returns to the shell (via $?) after it finishes running, indicating whether the request succeeded and, if not, why. Unlike HTTP status codes returned by the server, exit codes describe the outcome of the curl command itself — DNS failure, connection timeout, SSL handshake error, and so on.
This tool lets you look up any exit code (1-99) to see its meaning and the most common causes, or filter the full reference table by code, constant name, or keyword. It is aimed at debugging failures in CI/CD pipelines, cron jobs, and shell scripts where curl is used to call APIs or download files.
How to Use
-
Enter the exit code number
Type the code you got from
echo $?after a failed curl command into the lookup box. - Read the meaning and common causes The tool shows what the code indicates and the situations that typically trigger it.
- Browse or filter the full table If you are not sure of the exact number, filter the reference table by keyword instead.
Tips for getting more out of it
- You can check the exit code immediately with
$?(Bash) or%errorlevel%(Windows). In shell scripts, branching likecurl ... || 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/--failoption. 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.
Use Cases
Debugging a failed CI/CD pipeline step
Quickly identify why a curl-based deploy or health-check step failed by looking up the exit code from the build log.
Diagnosing a silently failing cron job
Cron jobs rarely show output, so checking the logged exit code is often the fastest way to find the root cause.
Writing robust shell script error handling
Look up which codes indicate a retryable network issue versus a permanent error to branch your script logic accordingly.
Incident postmortems
Confirm exactly what class of failure (DNS, TLS, timeout) occurred when reviewing logs after an outage.
Glossary
- Exit code
- A number a program returns to the shell on exit. 0 means success; curl uses 1-99 to indicate specific failure types.
- CURLcode
- The internal enum in libcurl that defines each error type. curl's command-line exit codes map directly to this enum.
- libcurl
- The C library that implements curl's core transfer logic. The curl command-line tool is a thin wrapper around it.
- --fail / -f flag
- A curl option that makes HTTP error responses (400+) produce exit code 22 instead of the default exit code 0.
- Connection timeout vs. connection refused
- Timeout (28) means no response arrived in time; refused/failed (7) means the TCP connection itself could not be established.
FAQ
echo $? in Bash/Zsh, echo %errorlevel% in the Windows Command Prompt, or $LASTEXITCODE in PowerShell.--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.).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.
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.