advanced19 min

Networking Inspection and curl Fundamentals

Reading curl's output and exit codes to distinguish a network failure from an HTTP-level failure, and the core flags for making requests, following redirects, and inspecting responses from the command line.

What you'll learn

  • Explain the difference between curl failing to connect at all and curl successfully receiving an HTTP error response
  • Use curl's core flags to control method, headers, request body, and redirect following
  • Explain why curl's own exit code alone is not sufficient to detect an HTTP-level failure like a 404 or 500

Prerequisites

Explanation

Every real command below runs only in your own terminal — this lesson's exercises model these decisions as data, never sending a real network request.

curl's own exit code tells you only whether curl itself succeeded at the networking mechanics — it resolved the hostname, connected, sent the request, and received some response. A non-zero curl exit code means something failed at that level: the hostname didn't resolve, the connection was refused or timed out, or (with certificate verification enabled) a TLS handshake failed. Critically, curl exiting 0 (success) does not mean the request "succeeded" in the sense a script usually cares about — a server responding with a 404 Not Found or a 500 Internal Server Error is still, from curl's networking-mechanics point of view, a fully successful exchange: curl connected, sent the request, and received a complete, valid HTTP response — it just happens to carry an error status.

This is why scripts that care about the actual HTTP status need to check it explicitly, not just rely on curl's exit code — either with curl's own --fail flag (which makes curl itself exit non-zero on an HTTP 4xx/5xx response, when you want that specific behavior) or by capturing the status code directly with -w "%{http_code}" and checking it in the script. Confusing these two failure levels — network-layer failure vs. HTTP-layer failure — is a genuinely common source of scripts that silently treat a real API error as a success, simply because curl itself didn't complain.

curl's most-used flags for everyday inspection: -s (silent, suppress the progress meter — useful in scripts), -i (include response headers in the output), -I (fetch only the headers, via a HEAD request), -L (follow redirects, which curl does not do by default), -X (set the HTTP method explicitly, like -X POST), -H (add a request header), and -d (send a request body, also implicitly setting the method to POST if none was specified).

Example

Modeling the distinction between curl's networking-level exit code and the HTTP-level status code it receives, as data.

function curlWouldSucceedAtNetworkingLevel(scenario) {
  // Models curl's OWN exit code: 0 only if the networking mechanics themselves worked.
  const networkFailures = ["dns-resolution-failed", "connection-refused", "tls-handshake-failed"];
  return !networkFailures.includes(scenario);
}
console.log(curlWouldSucceedAtNetworkingLevel("http-404-response")); // true -- curl DID successfully receive a full response
console.log(curlWouldSucceedAtNetworkingLevel("connection-refused")); // false -- curl itself failed at the networking level

function isHttpLevelFailure(statusCode) {
  return statusCode >= 400;
}
console.log(isHttpLevelFailure(404)); // true -- an HTTP-level failure, even though curl itself succeeded at connecting
console.log(isHttpLevelFailure(200)); // false -- a genuine, complete success at both levels

Try it yourself

Call isHttpLevelFailure with 500, and confirm a server error is correctly identified as an HTTP-level failure.

Code editor. Press Escape then Tab to leave the editor if keyboard focus becomes trapped. Press Control+Shift+M inside the editor to toggle Tab-key focus trapping.

Loading editor…

Guided exercise

Guided exercise

This models choosing curl's core flags for a scenario only -- no real request is sent. Write chooseCurlFlags(needsRedirects, method, hasBody): start with ['-s'] (always silent); add '-L' if needsRedirects; add '-X' + method if method is not 'GET'; add '-d' if hasBody. Return the array in that exact order.

Checks: chooses the minimal flag set for a plain GET · adds -L when redirect-following is needed · adds -X and -d correctly for a non-GET request with a body

Code editor. Press Escape then Tab to leave the editor if keyboard focus becomes trapped. Press Control+Shift+M inside the editor to toggle Tab-key focus trapping.

Loading editor…

Stuck? Get a hint.

Independent exercise

Independent exercise

This models distinguishing a network-level failure from an HTTP-level failure only -- no real request is sent. Write classifyOutcome(curlExitCode, httpStatus): if curlExitCode is not 0, return 'network-failure'. Otherwise, if httpStatus >= 400, return 'http-failure'. Otherwise, return 'success'.

Checks: correctly identifies a network-layer failure · correctly identifies an HTTP-layer failure despite curl itself succeeding · correctly identifies a genuine, complete success

Code editor. Press Escape then Tab to leave the editor if keyboard focus becomes trapped. Press Control+Shift+M inside the editor to toggle Tab-key focus trapping.

Loading editor…

Stuck? Get a hint.

Common mistakes

  • Assuming curl exiting 0 means the request 'succeeded' in every sense -- curl exits 0 as long as it successfully sent the request and received a complete response, even if that response is an HTTP 404 or 500.
  • Forgetting -L when a URL might redirect -- curl does NOT follow redirects by default, so a script can silently receive an unexpected redirect response instead of the final target's actual content.
  • Not checking the actual HTTP status code in a script that cares about it -- either via --fail (making curl itself exit non-zero on 4xx/5xx) or by capturing it explicitly with -w "%{http_code}", rather than assuming curl's own exit code covers this.

Knowledge check

Knowledge check

1. If curl exits with code 0 after a request that received an HTTP 500 response, what does that tell you?
2. Why must -L be added explicitly to follow an HTTP redirect with curl?
3. What's the correct way for a script to detect that a request received an HTTP 404, if curl's own exit code alone isn't sufficient?

Takeaway

curl's exit code reflects only the networking mechanics -- a complete, successfully received HTTP error response still counts as curl 'succeeding.' Use --fail or -w "%{http_code}" when a script needs to react to the actual HTTP status. Remember curl does not follow redirects unless -L is explicitly passed.

Summary

curl's own exit code tells you whether the networking mechanics worked (DNS, connection, TLS, receiving a complete response) -- not whether the HTTP status itself was a success. -L follows redirects (off by default). -X sets the method, -H adds headers, -d sends a body. --fail or -w "%{http_code}" are how a script actually checks the HTTP-level outcome.

References

Your notes

Notes save automatically.