keepcalculator

06 Numbers and Powers

Curl Follow Redirect: How to Use -L

Card No. 06·8311 · Updated · Standard formula, shown below

The calculator on this card is switched off while it is checked. The formula is below, and the worked example shows how to do the sum by hand.

Yes, curl follows redirects, but only when you explicitly tell it to with the -L (or --location) flag. Without that flag, curl fetches the initial URL and stops, showing you the 3xx redirect response instead of the final page. This article explains exactly how redirect handling works in curl, when to use -L, and how to avoid common pitfalls.

How curl Handles Redirects by Default

When you run curl https://example.com/old-page, curl sends a GET request and waits for the response. If the server replies with a 301, 302, 303, 307, or 308 status code plus a Location header, curl simply prints that response (headers included, if you use -i) and exits. It does not automatically request the new URL. This is intentional: many tools and scripts need to see the redirect itself, not silently follow it.

For example, a REST API might return 302 Found with a temporary URL for a resource. A client that blindly follows would miss the original response. curl’s default behavior gives you full control.

Using the -L Flag to Follow Redirects

To make curl follow redirects, add -L or --location:

curl -L https://example.com/old-page

Now curl will:

  • Send the initial request.
  • Read the redirect response.
  • Extract the URL from the Location header.
  • Send a new request to that URL.
  • Repeat until it gets a 200 OK (or another non-redirect status) or hits the maximum redirect limit.

By default, curl follows up to 50 redirects. You can change this with --max-redirs:

curl -L --max-redirs 10 https://example.com/old-page

If the limit is exceeded, curl stops and returns an error message like Maximum (10) redirects followed.

What Happens to POST and Other Methods?

This is where many people get confused. When curl follows a 301 or 302 redirect after a POST request, it changes the method to GET by default. That’s because HTTP standards (and most browsers) treat 301/302 as “movedâ€� and expect a GET for the new location. However, for 307 and 308 status codes, the HTTP spec requires that the method and body be preserved. curl honors that:

  • 301, 302, 303: POST becomes GET (unless you use --post301, --post302, or --post303 to force keeping POST).
  • 307, 308: Method and body are kept as-is.

If you’re sending a POST and you want it to be re-sent as POST after a redirect, use the appropriate flag:

curl -L --post302 -d "key=value" https://example.com/submit

Common Pitfalls and How to Avoid Them

Here are the most frequent issues people run into when following redirects with curl:

  • Losing headers or cookies: If the redirect goes to a different domain, curl by default does not forward the Authorization header or cookies unless you use --location-trusted and -b (cookie jar). For cross-domain redirects, this is a security feature.
  • Relative redirects: Some servers send a Location header like /new-page instead of a full URL. curl handles this correctly by resolving against the current URL, but if you’re parsing the header yourself, you must handle it.
  • Redirect loops: If two URLs point to each other, curl will keep following until it hits the max limit. Use --max-redirs to prevent infinite loops.
  • HTTPS to HTTP downgrade: By default, curl will follow a redirect from HTTPS to HTTP. If you want to block that, use --proto-redir or --proto =https to restrict protocols after the first request.

How to See the Redirect Chain

Sometimes you want to know which URLs were visited. Use -v (verbose) or -w (write-out) to see each step:

curl -L -v https://example.com/old-page

The verbose output shows each request line (> GET /old-page HTTP/1.1) and each response (< HTTP/1.1 301 Moved Permanently). For a cleaner list, use -w with %{url_effective} to print the final URL after following:

curl -L -o /dev/null -w "%{url_effective}\n" https://example.com/old-page

This prints the last URL after all redirects, which is useful for scripting.

Alternatives to curl for Redirects

If you’re not using curl, other tools have similar options:

  • wget: Follows redirects by default (no flag needed). Use --max-redirect to limit.
  • Python requests: Follows redirects automatically for GET, but you can disable with allow_redirects=False.
  • Node.js fetch: Follows redirects by default, with redirect: 'manual' to disable.

In scripts, always decide explicitly whether you want to follow redirects or not, because the default behavior varies between tools.

Security and Safety Considerations

Following redirects can expose you to unexpected destinations. A malicious server could redirect you to a phishing page or a local file URL (though curl blocks file:// by default unless you enable it). Always use --proto-redir to restrict protocols after the first request if you only want HTTP/HTTPS:

curl -L --proto-redir =https https://example.com

Also, be careful with --location-trusted: it sends sensitive headers (like Authorization) to any host the redirect points to, which can leak credentials. Only use it when you trust all involved domains.

Frequently Asked Questions

Does curl follow redirects by default?

No. Without -L, curl shows the redirect response (e.g., a 301 with a Location header) and stops. You must add -L to follow automatically.

How do I make curl follow redirects and save the final file?

Use -L together with -o filename. For example: curl -L -o final.html https://example.com/old-page. The file will contain the content from the final URL after all redirects.

Why does curl say “Maximum redirects followed� even with -L?

That means the server keeps sending redirects in a loop or the chain is longer than your --max-redirs value (default 50). Check the URLs with -v to see where it’s looping.

Does curl follow redirects for POST requests?

It depends on the status code. For 301/302/303, it converts POST to GET by default. For 307/308, it keeps the POST method and body. Use --post301, --post302, or --post303 to force keeping POST.

Can I stop curl from following a redirect to a different domain?

Yes, but there’s no built-in flag for that. You can use --proto-redir to restrict protocols, but for domain checks you’d need to script it: first get the redirect URL with -I (HEAD) and then decide whether to follow manually.

What’s the difference between -L and –location-trusted?

-L follows redirects but strips sensitive headers (like Authorization) on cross-host redirects. --location-trusted follows redirects and sends those headers to the new host as well, which is useful for internal APIs but risky for public sites.

Related

Formula used
in url | URL | - | https://example.com/redirect | 1 | 1000
in max | Max redirects | - | 5 | 0 | 50
out redirects | Redirects followed | - | 0 | 0

Each line is one input (in, sel, list) or one result (out: label, unit, formula, decimals). How the calculators work

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.

More cards in this drawer

The whole Numbers and Powers drawer →