Browsers cache, hide redirects and retry silently. curl shows exactly what a server returns, which makes it the fastest way to debug websites: redirect loops, caching headers, slow responses and SSL problems. It is installed on Linux, macOS and Windows 10/11.
Before you start
- A terminal. On Windows PowerShell type
curl.exe, because plaincurlis an alias for a different command in Windows PowerShell 5. - The URL you want to test.
View response headers
curl -I https://example.com-I sends a HEAD request and prints only headers. Some apps treat HEAD differently; to see headers from a real GET, use:
curl -sS -D - -o /dev/null https://example.comHeaders worth checking:
| Header | Tells you |
|---|---|
HTTP/2 200 | Protocol and status code |
location | Where a 301/302 redirects to |
server | Web server (LiteSpeed, nginx, cloudflare) |
cache-control, x-litespeed-cache, cf-cache-status | Whether the page is cached and where |
content-encoding | Compression (gzip, br) |
strict-transport-security | HSTS is enabled |
Ask for compression to see if it is offered: curl -sI -H 'Accept-Encoding: br,gzip' https://example.com | grep -i encoding.
Follow and trace redirects
curl -sIL https://example.com | grep -iE '^(HTTP|location)'-L follows redirects, printing each hop. A redirect loop shows the same two URLs alternating until curl stops at 50. Typical cause: HTTPS forced in both the app and a proxy/CDN that connects to the origin over HTTP.
Measure response time and TTFB
curl -o /dev/null -s -w 'dns: %{time_namelookup}s\nconnect: %{time_connect}s\ntls: %{time_appconnect}s\nttfb: %{time_starttransfer}s\ntotal: %{time_total}s\nstatus: %{http_code}\n' https://example.com- dns high: slow DNS provider.
- connect/tls high: distance to the server or network issues.
- ttfb much higher than tls: the server spends time generating the page (PHP, database, no cache).
Run it a few times; the first request may warm up caches.
Test a server before changing DNS
Migrating to a new server? Point curl at the new IP while DNS still shows the old one:
curl -I --resolve example.com:443:203.0.113.10 https://example.comThis sends the correct hostname and SNI to the new server, so virtual hosts and SSL behave exactly as they will after the switch.
Check SSL certificates
curl -vI https://example.com 2>&1 | grep -E 'subject:|issuer:|expire date:|SSL connection'This shows the TLS version, the certificate subject, issuer and expiry date. Errors such as SSL certificate problem: unable to get local issuer certificate mean the server is missing its intermediate (chain) certificate. For even more detail use openssl s_client -connect example.com:443 -servername example.com.
Other handy options
- Send a custom user agent:
-A 'Mozilla/5.0'(some firewalls block curl's default). - Test an API:
curl -X POST -H 'Content-Type: application/json' -d '{"a":1}' https://api.example.com/x - Basic auth:
-u user:pass. Force IPv4/IPv6:-4/-6. Skip cert checks for testing only:-k. - Bypass a cache: add a query string such as
?nocache=123.
Troubleshooting curl errors
- Could not resolve host: DNS problem or typo. Check with
dig example.com. - Failed to connect ... Connection refused: nothing listens on that port, or a firewall rejects it.
- Operation timed out: packets are dropped (firewall, routing) or the server is overloaded.
- SSL: no alternative certificate subject name matches: the certificate does not cover that hostname.
curl FAQ
Why does curl work but my browser does not?
The browser may be using cached DNS, cached redirects (301s are cached hard) or HSTS. Test in a private window or clear the site data.
Why does curl show 403 when the browser works?
A WAF or bot protection may block curl's user agent. Send a browser user agent to confirm.
Is there an online version?
Online header checkers exist, but running curl from your own machine and from the server itself tells you more.
