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.

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 chain | Result |
|---|---|
| 30, 40 and 50 | Followed to the end. Status 200, exit 0. |
| 51 and 60 | curl: (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:

| What we ran | Redirect | What arrived after the redirect |
|---|---|---|
curl -L -d 'name=alice' | 302 | GET, no form. |
curl -L -d 'name=alice' | 307 | POST with name=alice. |
curl -L --post302 -d 'name=alice' | 302 | POST with name=alice. |
curl -L -X POST -d 'name=alice' | 302 | POST with an empty body, on 8.5.0 and on 8.21.0. |
curl --follow -X POST -d 'name=alice' (8.21.0) | 302 | GET, no form. |
curl --follow -X POST -d 'name=alice' (8.21.0) | 307 | POST 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:
- Use
-dwithout-X POST. curl then picks GET or POST per redirect, as in the first two rows. - Add
--post301,--post302or--post303when the server expects the POST to survive that code. - Use
--followinstead of-Lwhen 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 see | Why | What to do |
|---|---|---|
A short page that says 301 Moved Permanently | curl showed the redirect instead of following it | Add -L. |
curl: (47) Maximum (50) redirects followed | A loop, or a very long chain | Check where it goes with -sIL --max-redirs 5. |
| The form data vanished after the redirect | A 301, 302 or 303 turned the POST into a GET | Add --post302, or fix the address so no redirect happens. |
| The server got a POST with no data | -X POST with -L | Drop -X POST, or use --follow on curl 8.16.0 and newer. |
401 on the redirected site | curl kept your -u login to the first host | Add --location-trusted if you trust the second host. |
| The login cookie is gone after the redirect | The cookie engine was off | Add -b '', or -b and -c with a cookie file. |
curl: (1) Protocol "file" not supported or disabled in libcurl | A redirect pointed at a protocol curl refuses | That 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.


