Tutorial

cURL follow redirects: -L, limits and redirects through a proxy

Make curl follow redirects with -L. We tested the 50-hop limit, what happens to a POST after 302 and 307, logins, cookies and proxies on 10 October 2026.

HProxy Team··Updated October 10, 2026·9 min read
HProxy.Tutorial

Skip the dead lists.

Our free proxy list re-checks every exit every few minutes across 100+ countries, with a live last-checked time, so you copy IPs that worked moments ago, not a stale text dump.

Open the free proxy list→

To make curl follow redirects, add -L (--location). Without it, curl stops at the first 3xx answer and shows you that answer, often a short page that says 301 Moved Permanently. With -L, curl requests the address in the Location header itself and keeps going, up to 50 times.

curl -L http://example.com/

We ran every command on this page on 10 October 2026, with curl 8.5.0 on Ubuntu 24.04 and the curl.exe 8.21.0 that Windows 11 ships. The redirects came from our own site, httpbin.org and a small redirect server on our own machine. A stub proxy and an echo server we wrote showed what a proxy and a second host receive.

Why does curl not follow redirects by default?

curl only does what you ask. A redirect is the server's answer, with a 3xx status code and a Location header that names the new address. curl's tutorial says it shows such pages like any other answer and follows them only when told.

Any curl works for the first steps, and What is cURL? explains how to find out which one you have. Every step below starts from our own site, which sends plain http:// visitors to https:// with a 301.

Terminal run of 10 October 2026, curl 8.5.0 on Ubuntu 24.04. Without -L, curl -s http://hproxy.com/ prints a page titled 301 Moved Permanently and exits 0. -w redirect_url prints 301 -> https://hproxy.com/. curl -sIL shows HTTP/1.1 301, the Location header and HTTP/2 200. With -L, -w prints 1 redirect, ended at https://hproxy.com/ with 200. httpbin's five-hop chain ends at https://httpbin.org/get. --max-redirs 3 stops it with curl: (47) Maximum (3) redirects followed. -L with --max-redirs 0 also ends with exit 47.
Our own run on our server, 10 October 2026, 20:10 UTC: curl 8.5.0 on Ubuntu 24.04, captured off-screen. Each command is printed before its output, then its exit code.

Step 1: see the redirect without following it

curl -s http://hproxy.com/
curl -s -o /dev/null -w '%{http_code} -> %{redirect_url}\n' http://hproxy.com/

The first command printed Cloudflare's small 301 Moved Permanently page and exited 0. The second printed 301 -> https://hproxy.com/. The redirect_url variable shows where a redirect would go, which is handy in scripts that check links.

Step 2: follow it with -L

curl -sIL http://hproxy.com/
HTTP/1.1 301 Moved Permanently
Location: https://hproxy.com/
HTTP/2 200

-I with -L prints the headers of every hop, which shows the whole chain. To report on the result instead, use -w:

curl -sL -o /dev/null -w '%{num_redirects} redirect, ended at %{url_effective} with %{http_code}\n' http://hproxy.com/

That printed 1 redirect, ended at https://hproxy.com/ with 200.

Step 3: set a limit

--max-redirs sets how many hops curl accepts. httpbin.org's /redirect/5 sends five in a row. Without a limit curl followed all five and ended at https://httpbin.org/get. With --max-redirs 3 it stopped:

$ curl -sSL --max-redirs 3 -o /dev/null https://httpbin.org/redirect/5
curl: (47) Maximum (3) redirects followed

Exit 47 is "too many redirects" in curl's manual. -1 removes the limit, which is risky on addresses you do not control.

How many redirects does curl follow by default?

The curl command follows 50. We built a chain of redirects on our own machine and counted:

Hops in the chainResult
30, 40 and 50Followed to the end. Status 200, exit 0.
51 and 60curl: (47) Maximum (50) redirects followed. Exit 47.

Some guides say 30, and so does the everything curl book. That is libcurl's default, which programs get when they call the library directly: its documentation gives 30 since version 8.3.0. The command line tool sets its own limit of 50, as its manual says and our run shows.

One more detail from our run: -L --max-redirs 0 is not the same as leaving out -L. It stopped at the first redirect with exit 47, while a command without -L exits 0.

What happens to a POST after a redirect?

After a 301, 302 or 303, curl repeats a POST as a GET and drops the data. After a 307 or 308 it keeps the POST and the data. RFC 9110 explains the split: for historical reasons a client may turn POST into GET after 301 and 302, a 303 means GET, and a 307 must keep the method. curl's manual says it follows the browsers' habit to stay consistent with them.

We sent the form field name=alice to httpbin.org, which redirected it to an address that echoes what arrives:

Two terminal captures from 10 October 2026, one above the other, curl 8.5.0 on Ubuntu 24.04. Above: a POST that meets a 302 arrives as GET with an empty form. After a 307 it arrives as POST with name alice. With --post302 the POST keeps the form after a 302. With -X POST and -L it arrives as POST with an empty form and empty data. Below: -u USER:PASS with a redirect to an echo server on 127.0.0.1 arrives without Authorization. With --location-trusted it carries Authorization Basic VVNFUjpQQVNT. A redirect to file:///dev/null ends with curl: (1) Protocol file not supported or disabled in libcurl. Through a stub proxy, the log shows GET http://hproxy.com/ and then CONNECT hproxy.com:443, both with the login.
Our own runs on our server, 10 October 2026, 20:11 UTC: curl 8.5.0 on Ubuntu 24.04, a stub proxy and an echo server we wrote, both listening on 127.0.0.1.
What we ranRedirectWhat arrived after the redirect
curl -L -d 'name=alice'302GET, no form.
curl -L -d 'name=alice'307POST with name=alice.
curl -L --post302 -d 'name=alice'302POST with name=alice.
curl -L -X POST -d 'name=alice'302POST with an empty body, on 8.5.0 and on 8.21.0.
curl --follow -X POST -d 'name=alice' (8.21.0)302GET, no form.
curl --follow -X POST -d 'name=alice' (8.21.0)307POST with name=alice.

The fourth row is the trap. The manual says that with -L, the method you set with -X is used for every request. After the 302, curl dropped the data as usual but kept the word POST, so the server got a POST with nothing in it. A Stack Overflow question from 2017, "curl uses POST for all requests after redirect", describes the same surprise.

There are three clean ways to handle a POST:

  1. Use -d without -X POST. curl then picks GET or POST per redirect, as in the first two rows.
  2. Add --post301, --post302 or --post303 when the server expects the POST to survive that code.
  3. Use --follow instead of -L when you need -X. It arrived in curl 8.16.0 and switches to GET after 301, 302 and 303, as our Windows 11 run with curl 8.21.0 showed.

The cURL POST guide covers forms, JSON and uploads in full.

Does curl send your login to the redirected site?

Not to another host. The manual says curl sends credentials from -u only to the first host. We sent -u USER:PASS to httpbin.org and let it redirect curl to an echo server on our own machine. The echo server received no Authorization header. With --location-trusted added, it received Authorization: Basic VVNFUjpQQVNT, which is USER:PASS in Base64.

Use --location-trusted only when you trust every host in the chain. A login in a custom header, such as X-Api-Key, gets no such protection. Our cURL headers guide shows such a header following the redirect to another host.

Can a redirect send curl somewhere dangerous?

curl limits where a redirect may lead. By default it follows redirects only to HTTP, HTTPS, FTP and FTPS, and --proto-redir changes the list. When httpbin.org redirected curl to file:///dev/null, curl refused:

$ curl -sSL 'https://httpbin.org/redirect-to?url=file:///dev/null'
curl: (1) Protocol "file" not supported or disabled in libcurl

Keep --max-redirs at a sane number for addresses you do not control. The default of 50 already stops an endless loop.

How do you keep cookies across a redirect?

Some sites set a cookie in the redirect itself and expect it on the next page. curl only keeps such cookies when its cookie engine is on. httpbin.org's /cookies/set address sets a cookie and redirects to a page that lists the cookies it received:

$ curl -sL https://httpbin.org/cookies/set?session=abc
{"cookies":{}}
$ curl -sL -b '' https://httpbin.org/cookies/set?session=abc
{"cookies":{"session":"abc"}}

-b '' turns the engine on with no cookies to start with. To keep cookies between commands, read them with -b cookies.txt and save them with -c cookies.txt.

Do redirects go through the proxy too?

Yes. With -x, every hop goes through the proxy. We followed our own site's redirect through a stub proxy on our server that asked for the login USER:PASS:

curl -sL -x http://127.0.0.1:18081 -U USER:PASS -o /dev/null -w '%{num_redirects} redirect, ended with %{http_code}\n' http://hproxy.com/

curl printed 1 redirect, ended with 200. The proxy's log showed two requests, both with the login: GET http://hproxy.com/ for the plain first hop, then CONNECT hproxy.com:443 for the encrypted second one. A proxy therefore sees every address in the chain. It sees the full request on http:// hops and only the host name on https:// ones.

The proxy flags work the same as on any request; how to use proxies with curl covers them. On a real gateway the same job takes -x http://premium.hproxy.com:10000 -U USER:PASS, with your own login from the dashboard of our residential proxies.

What goes wrong most often?

What you seeWhyWhat to do
A short page that says 301 Moved Permanentlycurl showed the redirect instead of following itAdd -L.
curl: (47) Maximum (50) redirects followedA loop, or a very long chainCheck where it goes with -sIL --max-redirs 5.
The form data vanished after the redirectA 301, 302 or 303 turned the POST into a GETAdd --post302, or fix the address so no redirect happens.
The server got a POST with no data-X POST with -LDrop -X POST, or use --follow on curl 8.16.0 and newer.
401 on the redirected sitecurl kept your -u login to the first hostAdd --location-trusted if you trust the second host.
The login cookie is gone after the redirectThe cookie engine was offAdd -b '', or -b and -c with a cookie file.
curl: (1) Protocol "file" not supported or disabled in libcurlA redirect pointed at a protocol curl refusesThat is curl protecting you. Do not widen --proto-redir.

What this page could not check

Our redirects came from our own site, httpbin.org and a test server on our machine; other servers may answer differently. --follow ran only on curl.exe 8.21.0, because Ubuntu 24.04's curl 8.5.0 predates it. The echo server and the stub proxy were ours. Redirects done with JavaScript or a meta refresh tag were not tested: curl's -L only follows a Location header on a 3xx answer. The POST with an empty body was one run per version against one server. curl releases about every eight weeks, so we will check this page again by 10 January 2027.

Sources

  • The curl man page, describing version 8.23.0, read 10 October 2026: curl.se/docs/manpage.html.
  • libcurl documentation, CURLOPT_MAXREDIRS, read 10 October 2026: curl.se/libcurl/c/CURLOPT_MAXREDIRS.html.
  • curl project, HTTP scripting tutorial, read 10 October 2026: curl.se/docs/httpscripting.html.
  • everything curl, Redirects, read 10 October 2026: everything.curl.dev.
  • RFC 7617 (September 2015), for the Base64 form of a Basic login: rfc-editor.org/rfc/rfc7617.
  • RFC 9110, HTTP Semantics, June 2022, sections on 301, 302, 303, 307 and 308: rfc-editor.org/rfc/rfc9110.
  • Stack Overflow, "curl uses POST for all requests after redirect", asked 27 January 2017, read through the Stack Exchange API on 10 October 2026.
  • Our own redirect tests of 10 October 2026, with curl 8.5.0 on Ubuntu 24.04 and curl.exe 8.21.0 on Windows 11. They ran against our own site, httpbin.org, a redirect chain, an echo server and a stub proxy on our machine. Each transcript, capture and script sits in this page's research folder.

Frequently asked questions

How do I make curl follow redirects?
Add -L, or its long form --location: curl -L http://example.com/. Without it curl stops at the first 3xx answer and prints that answer, often a short page that says 301 Moved Permanently.
How many redirects does curl follow?
The curl command follows 50 at most. In our test a chain of 50 finished, and a chain of 51 ended with curl: (47) Maximum (50) redirects followed. Change the limit with --max-redirs, or use -1 for no limit. Programs that use libcurl directly get a default of 30 since libcurl 8.3.0.
Why does my POST become a GET after a redirect?
curl repeats a POST as a GET without the data after a 301, 302 or 303, as browsers do. After a 307 or 308 it keeps the POST. To keep the POST after a 301, 302 or 303, add --post301, --post302 or --post303.
Should I use -X POST with -L?
Usually not. With -L, curl uses the -X method for every request. In our test the request after a 302 became a POST with an empty body. Use -d alone, add --post302, or use --follow from curl 8.16.0, which switches to GET after 301, 302 and 303 as the HTTP rules allow.
Does curl send my password to the redirected site?
Not to another host. curl sends a login given with -u only to the first host, and our test showed no Authorization header after a redirect to another host. --location-trusted sends it on, so use it only when you trust every host in the chain.
How do I see where a redirect goes without following it?
Run curl -s -o /dev/null -w '%{redirect_url}' with the address and no -L. curl prints the address the redirect points to. With -L, -w '%{url_effective}' prints the final address and %{num_redirects} the number of hops.
How do I keep cookies across a redirect?
Turn on curl's cookie engine with -b, for example curl -L -b '' URL, or -b cookies.txt -c cookies.txt to read and save them. In our test, a cookie set during the redirect reached the next hop only with -b ''.

Get proxies that are alive right now

Our free proxy list re-checks every exit every few minutes across 100+ countries, with a live last-checked time, so you copy IPs that worked moments ago, not a stale text dump. When the location has to survive a real check, the paid network holds up.

129M+ proxy checks run · 100+ countries · HTTP / HTTPS / SOCKS · re-checked every few minutes · no signup

HProxy.

Honest guides and comparisons on proxies, scraping and staying unblocked, from the team that runs the network.

RSS feed