Why cURL Doesn't Follow Redirects by Default (and How to Fix It)
ArticleWhen you make an HTTP request with **cURL**, the tool talks directly to a server and returns the response.
When you make an HTTP request with cURL, the tool talks directly to a server and returns the response. But unlike web browsers, cURL does not automatically follow redirects, that is, it does not automatically make a second request when the server says a resource has moved using an HTTP 3xx status code (e.g., 301, 302, 303).
This behavior can be surprising if you expect cURL to behave like Chrome or Firefox, which follow redirects silently behind the scenes. But because cURL is intended as a predictable command-line HTTP client, it waits for explicit instructions before following redirect chains.
Understanding how to enable and control redirect following is important when debugging web services, downloading from URLs that redirect, or working with APIs that may issue temporary or permanent redirects.
Why cURL Doesn’t Follow Redirects by Default
Servers send redirects using HTTP responses in the 300–399 range. These responses include a Location header telling the client where to go next. For example:
HTTP/1.1 301 Moved Permanently Location: https://example.com/new-location |
|---|
By default, cURL displays this response without going to the new Location. That gives developers control to inspect the redirect itself or handle it manually, which is useful in scripts and debugging environments.
Enabling Redirect Following: -L / --location
To make cURL follow redirects automatically, you use the -L option (a shorthand for --location). This tells cURL to follow the redirect using the URL provided in the Location header.
Here’s a basic example:
curl -L https://example.com/redirect |
|---|
In this command:
- cURL sends an HTTP request to
https://example.com/redirect. - If the server responds with a redirect, cURL follows the new URL.
- The final response (after all redirects) is printed to the terminal.
You can use curl -L -o page.html https://example.com/redirect to save the final output to a file.
Defaults and Limits
When you use -L, cURL will follow up to 50 redirects by default. That limit prevents the tool from getting stuck in infinite loops created by misconfigured servers.
If you want to change the maximum number of redirects cURL follows, use --max-redirs:
curl -L --max-redirs 10 https://example.com/redirect |
|---|
This command tells cURL to stop after 10 redirects even if more are present.
How Redirects Work with Different HTTP Methods
By default, when cURL follows a redirect with -L, it will change POST requests to GET for the follow-up requests for common redirect codes like 301, 302, and 303. This behavior mirrors how many browsers handle such redirects, but it may not be appropriate in all contexts, especially when submitting data.
If you need to preserve the original method (such as POST) during redirects, cURL provides flags like --post301, --post302, and --post303 to maintain that method across redirects, although you should choose them carefully based on your server’s expectations.
Debugging and Seeing Redirect Chains
To see each step of a redirect (including headers and intermediate URLs), you can combine -L with verbose output -v:
curl -L -v https://example.com/redirect |
|---|
This prints detailed information showing each request and response during the redirect process, helping you understand where and how the redirects occur.
Handling Credentials and Security
When you use -L, cURL is cautious about your privacy. By default, if a redirect takes you to a different host (e.g., from mysite.com to othersite.net), cURL will not send your authentication credentials (username and password) to the new host. This prevents sensitive data from leaking to an untrusted third party.
However, if you are working within a trusted environment and need those credentials to persist across different domains, you can use --location-trusted. This tells cURL to pass the authentication headers even if the hostname changes.
Warning: Use this flag sparingly. Only use --location-trusted if you are certain that every potential destination in the redirect chain is under your control.
Pro Tip: Extracting Only the Final URL
Sometimes you don't actually want the content of the page; you just want to know where a shortened or redirected link ends up. Instead of parsing a wall of verbose text, you can use the -w (write-out) variable url_effective.
Combine it with -s (silent) and -o /dev/null (to discard the body) like this:
curl -Ls -o /dev/null -w "%{url_effective}n" https://bit.ly/example-link |
|---|
This command will follow all redirects silently and then print only the final destination URL to your terminal. This is incredibly useful for cleaning up datasets of links or checking for broken "vanity" URLs in bulk.
Why cURL Can’t Follow Client-Side Redirects
It’s important to understand that cURL only handles server-side HTTP redirects. It cannot follow client-side redirects that are initiated by:
- JavaScript (e.g.,
window.location = …) - HTML meta refresh tags (e.g.,
<meta http-equiv="refresh" …>)
Those forms of redirects require a real browser or a headless browser that executes scripts, because cURL does not interpret HTML or run JavaScript.
Common Use Cases
Here are typical scenarios where following redirects with cURL matters:
- Downloading from URLs that redirect (for example, a shortened link that points to a final file).
- Testing API endpoints that include redirect logic.
- Debugging web applications that change structure and send old URLs to new ones.
- Automated scripts that need to reliably reach the final resource without manual intervention.
Conclusion
The curl follow redirect feature (enabled with -L) brings cURL’s behavior closer to what browsers do, but still gives developers control over how many hops to follow and how to handle HTTP methods and debugging. Understanding how to use this option lets you work effectively with real-world URLs and services that rely on 3xx redirects.
If you encounter issues where cURL doesn’t reach the final content you expect, first check whether a redirect is involved and then try adding -L to your command to see the full result after automatic redirections.
Find more insights here
How to Use a SOCKS5 Proxy Server
A SOCKS5 proxy is simply a piece of infrastructure that sits between your device and the internet an...
Spotify Profiles Search Scraper: How It Works and Why Developers Use It
Unlock music market insights by scraping Spotify user profiles. Learn the best tools for keyword-bas...
Facebook Marketplace API: What Developers Need to Know in 2026
Learn why Meta doesn't offer a public endpoint and discover the 3 best ways developers programmatica...