Skip to content

/codes/curl/curl-exit-codes

curl exit codes: 6, 7, 22, 28, 35, 56, 60 and the rest

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · curl 8.21.0 (x86_64-w64-mingw32) libcurl/8.21.0 Schannel zlib/1.3.2updated
tool
curl
versions
curl 7.x, curl 8.x
os
linux, macos, windows

curl's exit code tells a script why a transfer failed: 0 means success, and every other value maps to a libcurl error such as 6 (could not resolve the host), 7 (could not connect), 22 (HTTP status 400 or above, only with -f) or 28 (timeout). The number is also printed in the error message, curl: (7) .... With -sS, curl hides the progress meter but still prints that message to stderr.

Common exit codes

Codelibcurl nameMeaningTypical cause
0CURLE_OKSuccessThe transfer completed (HTTP errors too, unless -f is used)
1CURLE_UNSUPPORTED_PROTOCOLUnsupported protocolTypo in the scheme (htp://) or a protocol not built in
3CURLE_URL_MALFORMATMalformed URLSpaces or invalid characters in the URL
5CURLE_COULDNT_RESOLVE_PROXYCould not resolve proxyWrong host in http_proxy / https_proxy
6CURLE_COULDNT_RESOLVE_HOSTCould not resolve hostTypo in the host name, no DNS, offline
7CURLE_COULDNT_CONNECTFailed to connectNothing listening on the port, firewall reject
18CURLE_PARTIAL_FILEPartial fileConnection closed before the announced size arrived
22CURLE_HTTP_RETURNED_ERRORHTTP errorStatus 400 or above with -f / --fail
23CURLE_WRITE_ERRORWrite errorOutput directory missing, disk full, closed pipe
26CURLE_READ_ERRORRead errorFile given to -T or -d @file cannot be read
28CURLE_OPERATION_TIMEDOUTTimeout--max-time or --connect-timeout reached
35CURLE_SSL_CONNECT_ERRORTLS handshake failedProtocol or cipher mismatch, plain HTTP on a TLS port
47CURLE_TOO_MANY_REDIRECTSToo many redirectsRedirect loop with -L (limit set by --max-redirs)
52CURLE_GOT_NOTHINGEmpty reply from serverServer closed the connection without answering
56CURLE_RECV_ERRORReceive failureConnection reset while reading the response
60CURLE_PEER_FAILED_VERIFICATIONCertificate problemSelf-signed, expired or wrong-host certificate

The full list, more than 90 codes, is in the libcurl error documentation. Codes that are no longer used stay reserved, so the numbers never change meaning.

Seen in practice

Each command below fails in a different way against local addresses (ports 4303 and 4304) or with a malformed URL:

bash
node -e 'require("http").createServer((q, r) => { if (q.url === "/slow") setTimeout(() => r.end("late\n"), 2500); else { r.statusCode = 500; r.end("error\n"); } }).listen(4303, "127.0.0.1"); setTimeout(() => process.exit(0), 5000)' &
sleep 1
run() { curl -sS "$@" 2>&1 | sed -E 's/[0-9]+ (ms|milliseconds)/N \1/'; echo "  -> exit ${PIPESTATUS[0]}"; }
run htp://127.0.0.1:4303/
run 'http://exa mple.com/'
run http://127.0.0.1:4304/
run -o /dev/null -f http://127.0.0.1:4303/
run -o /dev/null --max-time 1 http://127.0.0.1:4303/slow
wait

Output

curl: (1) Protocol "htp" not supported
  -> exit 1
curl: (3) URL rejected: Malformed input to a URL function
  -> exit 3
curl: (7) Failed to connect to 127.0.0.1:4304 after N ms: Could not connect to server
  -> exit 7
curl: (22) The requested URL returned error: 500
  -> exit 22
curl: (28) Operation timed out after N milliseconds with 0 bytes received
  -> exit 28

Using the code in a script

bash
curl -fsS --max-time 10 -o data.json https://api.example.org/data
case $? in
  0)  echo "ok" ;;
  6)  echo "DNS problem" ;;
  7)  echo "service down" ;;
  22) echo "HTTP error" ;;
  28) echo "timed out" ;;
  *)  echo "other curl error" ;;
esac

curl -w '%{exitcode}' (curl 7.75.0 and later) prints the same number from inside the write-out format.

Sources