Site icon BitBook

Debug HTTP Redirects and Timing with curl

Sometimes you need to know where a URL really goes, how many redirects it takes to get there, and whether the slow part is DNS, TLS, the server, or the whole chain.

This is a good job for curl. The two pieces that matter are:

Show the Final URL, Status Code, Redirect Count, and Timing

Use this when you only care about the result and timing summary:

curl -sS -o /dev/null \
  -w 'url=%{url_effective}\ncode=%{http_code}\nredirects=%{num_redirects}\nnamelookup=%{time_namelookup}\nconnect=%{time_connect}\ntls=%{time_appconnect}\nttfb=%{time_starttransfer}\ntotal=%{time_total}\n' \
  -L 'http://bitbook.io/'

Example output:

url=https://www.bitbook.io/
code=200
redirects=1
namelookup=0.048693
connect=0.118501
tls=0.092983
ttfb=1.085987
total=1.106034

That says the original http://bitbook.io/ request ended at https://www.bitbook.io/, returned HTTP 200, and followed one redirect.

The timing values are seconds:

If time_namelookup is high, look at DNS. If time_appconnect is high, look at TLS or network latency. If time_starttransfer jumps while the earlier values are normal, the origin server or upstream application is usually where to look next.

Show the Header Chain

Use -I with -L when you want to see each redirect response:

curl -sS -I -L --max-redirs 5 'http://bitbook.io/'

Example output:

HTTP/1.1 301 Moved Permanently
Location: https://www.bitbook.io/
Server: cloudflare

HTTP/2 200
content-type: text/html; charset=UTF-8
server: cloudflare
cf-cache-status: DYNAMIC

This is the quick way to spot common redirect problems:

--max-redirs 5 is there on purpose. It keeps a broken redirect loop from running longer than needed. Increase it if you are debugging a known long chain, but most sites should not need many redirects.

Show One Line Per URL

For checking several URLs, put the output on one line:

while read -r url; do
  curl -sS -o /dev/null -L --max-redirs 5 \
    -w '%{http_code} %{num_redirects} %{time_total} %{url_effective}\n' \
    "$url"
done <<'URLS'
http://bitbook.io/
https://www.bitbook.io/
URLS

Example output:

200 1 1.106034 https://www.bitbook.io/
200 0 0.812451 https://www.bitbook.io/

That format is easy to paste into a ticket or compare before and after a DNS/CDN change.

Debug a POST or Authenticated Request Carefully

For APIs, add the method and headers you need:

curl -sS -o /dev/null -L --max-redirs 5 \
  -H 'Authorization: Bearer REPLACE_WITH_TOKEN' \
  -H 'Accept: application/json' \
  -w 'code=%{http_code} redirects=%{num_redirects} total=%{time_total} url=%{url_effective}\n' \
  'https://api.example.com/v1/account'

Do not paste real bearer tokens, cookies, or basic-auth passwords into shared terminals, screenshots, tickets, or blog comments. If you need verbose debugging, prefer redacting the output before sharing it.

Also be careful with -L on requests that include credentials. Redirects can move a request to a different host. Modern curl is cautious about forwarding sensitive headers across hosts, but you should still inspect the redirect target before sending production credentials.

Quick Verification

Run this against a URL that should redirect:

curl -sS -o /dev/null \
  -w 'code=%{http_code} redirects=%{num_redirects} final=%{url_effective}\n' \
  -L --max-redirs 5 'http://bitbook.io/'

Expected shape:

code=200 redirects=1 final=https://www.bitbook.io/

If redirects is 0, the URL did not redirect. If the command fails with Maximum redirects followed, you probably found a redirect loop or set --max-redirs too low.

The useful habit is to check both the header chain and the timing summary. The headers tell you where the request went. The timing numbers tell you where it got slow.

Exit mobile version