Troubleshooting flaky APIs or unexpected browser-like behavior often requires seeing the raw HTTP conversation between client and server. Detailed request and response data shows exact status codes, redirects, and headers such as Authorization, Set-Cookie, and Cache-Control. Inspecting this traffic clarifies whether a failure originates in the client, the network, or the remote service.
The curl command-line client exposes this detail with verbose and trace options that print connection events, TLS negotiation, and the full wire-level payload. Flags such as --verbose, --head, --include, and --trace-ascii annotate what is being sent and received, using consistent markers for metadata, headers, and body bytes. Combining these options provides both high-level summaries and low-level traces for any HTTP endpoint reachable from the host.
Verbose curl output and trace logs can contain sensitive information, including bearer tokens, cookies, query parameters, and portions of request or response bodies. Debugging should therefore take place on trusted machines, with logs stored in restricted directories and removed or redacted before sharing with others. The following commands assume curl is available in a shell environment on Linux, macOS, or Windows and that the working directory is writable for temporary trace files.
Steps to debug HTTP requests with verbose cURL output:
- Check the installed curl version to confirm protocol and feature support.
$ curl --version curl 8.5.0 (aarch64-unknown-linux-gnu) libcurl/8.5.0 OpenSSL/3.0.13 zlib/1.3 brotli/1.1.0 zstd/1.5.5 libidn2/2.3.7 libpsl/0.21.2 (+libidn2/2.3.7) libssh/0.10.6/openssl/zlib nghttp2/1.59.0 librtmp/2.3 OpenLDAP/2.6.7 Release-Date: 2023-12-06, security patched: 8.5.0-2ubuntu10.6 Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM PSL SPNEGO SSL threadsafe TLS-SRP UnixSockets zstd ##### snipped #####
Protocol and feature lines indicate whether HTTP2, proxies, and TLS backends are available, which can influence how debug output appears.
- Send a verbose GET request to observe connection setup, request headers, and the initial response status.
$ curl --verbose --silent --cacert /work/docker/certs/ca.crt https://api.example.net/headers * Host api.example.net:443 was resolved. * IPv6: (none) * IPv4: 127.0.0.1 * Trying 127.0.0.1:443... * Connected to api.example.net (127.0.0.1) port 443 * ALPN: curl offers h2,http/1.1 ##### snipped ##### > GET /headers HTTP/1.1 > Host: api.example.net > User-Agent: curl/8.5.0 > Accept: */* ##### snipped ##### < HTTP/1.1 200 OK < Server: sg-httpbin-lite/1.0 Python/3.12.3 < Date: Sat, 10 Jan 2026 05:12:36 GMT < Content-Length: 105 < Content-Type: application/json ##### snipped #####
Lines prefixed with * describe connection events, lines prefixed with > show outgoing HTTP data, and lines prefixed with < show response headers from the server.
- Focus on status codes and headers without downloading the body by issuing a verbose HEAD request.
$ curl --verbose --head --silent --cacert /work/docker/certs/ca.crt https://api.example.net/headers ##### snipped ##### > HEAD /headers HTTP/1.1 > Host: api.example.net ##### snipped ##### < HTTP/1.1 200 OK < Content-Type: application/json ##### snipped #####
HEAD requests are efficient for investigating redirect behavior, cache settings, and content negotiation because only metadata is transferred.
- Capture a complete ASCII trace with timestamps into a log file for deeper inspection of a problematic endpoint.
$ curl --silent --trace-ascii debug-http.log --trace-time --cacert /work/docker/certs/ca.crt https://api.example.net/headers { "headers": { "Accept": "*/*", "Host": "api.example.net", "User-Agent": "curl/8.5.0" } }Trace logs such as debug-http.log can contain cookies, bearer tokens, and request payloads, so store them on trusted systems and remove them after debugging to avoid leaking secrets.
- Inspect the beginning of the trace log to confirm that connection metadata and timestamps were recorded.
$ head -n 12 debug-http.log 05:12:37.411475 == Info: Host api.example.net:443 was resolved. 05:12:37.411535 == Info: IPv6: (none) 05:12:37.411536 == Info: IPv4: 127.0.0.1 05:12:37.411546 == Info: Trying 127.0.0.1:443... 05:12:37.411586 == Info: Connected to api.example.net (127.0.0.1) port 443 05:12:37.412470 == Info: ALPN: curl offers h2,http/1.1 05:12:37.412550 => Send SSL data, 5 bytes (0x5) 0000: ..... 05:12:37.412570 == Info: TLSv1.3 (OUT), TLS handshake, Client hello (1): ##### snipped #####
Markers like == Info:, => Send header, and <= Recv header label diagnostic events and differentiate them from raw protocol bytes.
- Verify the request behavior by searching the trace log for HTTP status lines and key headers that match expectations.
$ grep -Ei '^0000: HTTP/|^0000: location:|^0000: content-type:' debug-http.log 0000: HTTP/1.1 200 OK 0000: Content-Type: application/json ##### snipped #####
Successful behavior typically shows expected status codes such as 200 or 204, correct Location targets for redirects, and a Content-Type consistent with the API contract.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
