Skip to content
shellmap

Follow HTTP redirects

Print the redirect chain (301/302/303/307/308 hops) from a starting URL to its final 2xx destination.

How to follow http redirects in each shell

Bashunix
curl -sSLI -o /dev/null -w "%{url_effective}\n" https://bit.ly/3xyz
Zshunix
curl -sSLI -o /dev/null -w "%{url_effective}\n" https://bit.ly/3xyz
Fishunix
curl -sSLI -o /dev/null -w "%{url_effective}\n" https://bit.ly/3xyz
PowerShellwindows
(Invoke-WebRequest -Uri https://bit.ly/3xyz -MaximumRedirection 10).BaseResponse.RequestMessage.RequestUri

`Invoke-WebRequest` follows redirects by default — `-MaximumRedirection 0` disables to inspect the 30x response itself. `.BaseResponse.RequestMessage.RequestUri` is the FINAL URL on pwsh 7+. On pwsh 5.1 use `(iwr URL).Headers.Location` after `-MaximumRedirection 0`.

cmd.exewindows
curl -sSLI -o NUL -w "%{url_effective}" https://bit.ly/3xyz

`/dev/null` does not exist on Windows — use `NUL`. cmd `-w` format string uses `\n` but cmd's own batch quoting often eats it; in a `.bat` you may need `%{url_effective}^\n`.

Equivalents listed for Bash, Zsh, Fish, PowerShell, cmd.exe.

Gotchas & notes

  • `-L` (`--location`) follows redirects; without it, curl stops at the first 30x and prints its body (usually an empty redirect HTML stub). Combine with `-I` to see EACH hop's status line + headers — the output is multiple HTTP/1.1 blocks separated by blank lines.
  • Cap the chain: `curl --max-redirs 10 -L URL` (default is 50). Without a cap, a redirect loop (`A → B → A`) will spin until 50 hops are exhausted, then error. Most public shorteners (bit.ly, t.co, goo.gl-archived) have at most 1–2 hops; deeper chains usually indicate misconfigured server-side rewriting.
  • Body-leakage across hosts: when `curl -L` follows a redirect to a DIFFERENT origin, by default `Authorization:` and `Cookie:` headers are STRIPPED from the next request (CVE-2014-3613 fixed this). But custom headers (`-H "X-API-Key: …"`) are RE-SENT to the redirect target — if your `-H` carries a secret and the redirect is attacker-controlled, your secret leaks. Use `--location-trusted` ONLY when you trust every host in the chain.
  • Inspect just the final URL: `curl -sSLI -o /dev/null -w "%{url_effective}\n" URL`. The full status code chain: `curl -sSLI URL | awk '/^HTTP/ {print}'`. PowerShell version: `(Invoke-WebRequest URL).BaseResponse.RequestMessage.RequestUri.AbsoluteUri`. For richer trace: `curl --trace-ascii -` (HUGE output, use only when debugging).

Related commands

Related tasks