curl -v
Plain curl https://example.com prints a response body and nothing else — everything that happened to produce it stays invisible. Every layer this course has covered so far — the TCP handshake, the TLS handshake, the actual HTTP request and response — happens underneath that one silent body, and -v is the single flag that turns all of it back on.
Reading the three prefixes
* Trying 93.184.216.34:443...
* Connected to example.com (93.184.216.34) port 443
* ALPN: curl offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* ALPN: server accepted h2
* Server certificate:
* subject: CN=example.com
* issuer: C=US; O=Let's Encrypt; CN=R11
> GET / HTTP/2
> Host: example.com
> user-agent: curl/8.5.0
> accept: */*
>
< HTTP/2 200
< content-type: text/html; charset=UTF-8
< content-length: 1256
< date: Mon, 27 Jul 2026 09:58:11 GMT
<
<!doctype html>
<html>
...
Every line's leading character tells you which side of the exchange it belongs to:
*— informational lines fromcurlitself, not part of any protocol exchange: connecting, negotiating TLS, resolving ALPN.>— bytescurlactually sent — the request line and headers going out.<— bytes the server actually sent back — the status line and response headers coming in.- unprefixed — the response body, printed exactly as the plain, non-verbose version would show it.
Reading top to bottom, this single output confirms, in order: a TCP connection was established, TLS 1.3 was negotiated with a specific cipher suite, the server's certificate subject and issuer are what you'd expect, ALPN settled on HTTP/2 for both sides, the request that was actually sent, and the response status and headers that came back — each layer this course covered separately, visible together in one command's output.
ALPN: how the HTTP version gets decided before any HTTP happens
* ALPN: curl offers h2,http/1.1 and * ALPN: server accepted h2 are worth pausing on specifically, because they answer a question the HTTP evolution module leaves open: how does a client and server agree on HTTP/1.1 versus HTTP/2 before the first HTTP byte is even sent? ALPN (Application-Layer Protocol Negotiation) is a TLS extension that piggybacks that negotiation onto the handshake itself — the client lists which protocols it supports in its ClientHello, and the server picks one and confirms it in its response, all before the encrypted channel is even fully established. By the time > GET / HTTP/2 appears in the output above, that choice has already been made at the TLS layer; the HTTP request line is just confirming what ALPN already settled.
Plain HTTP: the same request, with no encryption to peel back
* Trying 93.184.216.34:80...
* Connected to example.com (93.184.216.34) port 80
> GET / HTTP/1.1
> Host: example.com
> user-agent: curl/8.5.0
> accept: */*
>
< HTTP/1.1 301 Moved Permanently
< location: https://example.com/
< content-length: 0
<
No ALPN, no certificate, no TLS handshake lines at all — port 80 skips straight from the TCP connection to the plain-text HTTP exchange, exactly as the HTTPS article described. The 301 response here is also the redirect-to-HTTPS behavior that same article covers: a properly configured site doesn't serve real content over plain HTTP at all, it bounces the client to the encrypted version immediately.
Where the output stops is the diagnosis
An API integration works from one server and hangs indefinitely from another, with no error, just silence:
* Trying 203.0.113.44:443...
* connect timeout after 5001ms
* Failed to connect to partner-api.example port 443 after 5002 ms: Timeout was reached
The output stopping after Trying — with curl -v never even reaching a * Connected to line — is a specific and useful signal on its own: the TCP handshake's very first SYN never got a response at all, which points at a firewall silently dropping the SYN somewhere in the path, or the port simply not being open there, rather than anything wrong at the TLS or HTTP layer. Compare that against a request that connects and completes TLS but then hangs waiting on the HTTP response itself — that would show the * Connected to and SSL connection using lines before stalling, pointing instead at the application on the other end being slow or unresponsive rather than a network-layer block. Where the output stops is itself the diagnosis.
Practice exercises
- Run
curl -vagainst an HTTPS site you use regularly and identify the negotiated TLS version, cipher suite, and ALPN result from the output. - Compare
curl -v http://example.comagainstcurl -v https://example.comfor the same domain, and list every line present in the HTTPS output that has no equivalent at all in the plain HTTP one. - Using the scenario above, explain what it would mean if a hung request's
curl -voutput showed* Connected toand the TLS handshake lines, but then stalled with no>request lines ever appearing at all.
Every tool in this module has worked from the outside of a connection — a name, a port, a status code, a set of headers. Seeing the actual frames as they cross the wire, byte for byte, rather than a summary one tool chose to print, is the next and final step, and it's what the rest of this module turns to next.