Examples use example.com and documentation IPs; swap in your target.

SymptomGoalCommandKey details
First look Headers only curl -I https://example.com/ HEAD request; some apps mishandle HEAD, so use -sS -D - -o /dev/null to test the real GET
See the wire curl -v -o /dev/null https://example.com/ * info, > sent, < received; output goes to stderr
Status only curl -sS -o /dev/null -w '%{response_code}\n' https://example.com/ -sS hides progress but keeps errors
Readable JSON body curl -sS https://api.example.com/users/42 | jq . -sS keeps the progress meter out of the pipe
Follow redirects curl -L http://example.com/ Exit 47 = too many redirects
Connection Is the port open? curl -v telnet://db.example.com:5432 "Connected to" = TCP is reachable; no nc or telnet needed. Exit 7 = connect failed
Which backend answered? curl -sS -o /dev/null -w '%{remote_ip}:%{remote_port} %{response_code}\n' https://example.com/ Shows where a load balancer, DNS round-robin, or VIP sent you
Bound the request curl --connect-timeout 3 --max-time 10 https://example.com/ --connect-timeout limits connection setup; --max-time the whole request. Exit 28 = timeout
Slow / flapping Phase timing curl -sS -o /dev/null -w 'dns=%{time_namelookup} conn=%{time_connect} tls=%{time_appconnect} ttfb=%{time_starttransfer} total=%{time_total}\n' https://example.com/ Cumulative times: high dns → resolver; conn−dns → network/firewall; tls−conn → handshake; ttfb−tls → server
Watch over time while true; do curl -sS -o /dev/null -w '%{response_code} %{time_total}\n' https://example.com/health; sleep 1; done Catches rollouts, intermittent 5xx, and failovers
DNS / routing Pin host to IP curl --resolve 'example.com:443:203.0.113.10' https://example.com/health Keeps SNI, cert check, and Host; exit 6 = DNS failed
Send to another backend curl --connect-to 'example.com:443:backend.internal:8443' https://example.com/health Like --resolve, but can also change the port
Hit an IP with a Host header curl -H 'Host: example.com' http://203.0.113.10/ Plain-HTTP virtual-host test; for HTTPS use --resolve so SNI matches
IPv4 vs IPv6 curl -4 https://example.com/ / curl -6 https://example.com/ Isolates a broken address family
TLS Cert subject / expiry curl -sv -o /dev/null https://example.com/ 2>&1 | grep -E 'subject:|issuer:|expire date:' Exit 60 = cert verification failed; exit 35 = handshake failed
Private CA curl --cacert ./internal-ca.pem https://service.internal/ Verifies the server with this PEM CA bundle
Mutual TLS curl --cert ./client.crt --key ./client.key --cacert ./ca.pem https://mtls.example.com/health Sends a client certificate
Exact TLS version curl --tlsv1.2 --tls-max 1.2 https://example.com/ --tlsv1.2 alone means 1.2 or newer
Confirm a cert issue curl -k https://dev.example.com/ Diagnosis only, never the fix
HTTP version Compare curl --http1.1 https://example.com/ / curl --http2 https://example.com/ Exit 16 / 92 = HTTP/2 error
Proxy Through a proxy curl -x http://proxy.example.com:8080 https://example.com/ Also reads http_proxy, HTTPS_PROXY, NO_PROXY
Bypass all proxies curl --noproxy '*' https://example.com/ Overrides the env vars
SOCKS / SSH tunnel curl --socks5-hostname 127.0.0.1:1080 https://internal.example.com/ The proxy resolves the hostname, e.g. through ssh -D 1080 jumphost
Local / container Unix socket curl --unix-socket /var/run/docker.sock http://localhost/version For Docker, containerd, and local daemons
API request Reproduce a browser request DevTools → Network → right-click → Copy as cURL Exact headers, cookies, and body; strip secrets before sharing
Any method, JSON body curl -X PATCH --json '{"name":"Alice","active":true}' https://api.example.com/users/42 -X sets the method name only (PUT, PATCH, …); without it a body means POST. --json adds the body plus Content-Type/Accept headers (curl 7.82+). Use -I, not -X HEAD, which hangs
Any method, form body curl -X PUT --data-urlencode 'name=Alice' --data-urlencode 'note=hello & bye' https://api.example.com/users/42 URL-encodes each field; Content-Type: application/x-www-form-urlencoded
GET with query curl -G --data-urlencode 'q=distributed systems' --data-urlencode 'page=2' https://api.example.com/search -G moves the data into the query string
Delete curl -X DELETE https://api.example.com/users/42 No body needed
Basic auth curl -u alice https://api.example.com/private Prompts for the password; exit 67 = auth rejected
Bearer token curl -H "Authorization: Bearer $API_TOKEN" https://api.example.com/private Token comes from an env var, not the command history
CORS preflight curl -i -X OPTIONS -H 'Origin: https://app.example.com' -H 'Access-Control-Request-Method: POST' https://api.example.com/users Check the Access-Control-Allow-* response headers
Fail on 4xx/5xx curl --fail-with-body https://example.com/missing curl 7.76+. Without it, a 404 or 500 still exits 0; with it, exit 22
Feature missing Check build curl --version Lists protocols, TLS backend, and features