
Learn how to resolve redirect loops caused by SSL, reverse proxy, www conflicts, and misconfigurations using proven production-ready methods.
Introduction
ERR_TOO_MANY_REDIRECTS is one of those issues that looks complicated at first, but in reality, it usually comes down to a few misaligned configurations. When a browser shows this error, it simply means the request is being redirected in a loop and never reaches a final response.
In most real-world setups, this happens when Nginx, the application, or an external service like a CDN are all trying to control redirects at the same time. The key to fixing it is not adding more rules, but simplifying and aligning them.
Prerequisites
Before we begin, let’s ensure we have the following in place:
- A Linux OS installed on dedicated server or KVM VPS.
- A basic programming knowledge.
- Nginx installed
Start with Configuration Validation
We always begin by confirming that Nginx itself is not the problem. A broken configuration can create unpredictable behavior, including redirect loops.
Run:
sudo nginx -t
If Nginx reports any issue, fix that first before moving forward. A valid configuration is the foundation of everything else.
Understand Where the Loop Is Coming From
A redirect loop usually involves two endpoints sending traffic back and forth. The most common patterns we see are:
- HTTP redirecting to HTTPS while HTTPS redirects back to HTTP
- www redirecting to non-www while non-www redirects back to www
- Application forcing HTTPS while Nginx is already doing it
- Missing proxy headers causing the backend to misinterpret the request
Instead of guessing, we verify the behavior using:
curl -I -L http://example.com
This command shows the full redirect chain. If the same URLs repeat, we have identified a loop.
Fix HTTP to HTTPS Redirection Properly
One of the most common mistakes is duplicating redirect logic. We should define a single, clean redirect rule at the HTTP level and avoid repeating it elsewhere.
A correct and production-safe configuration looks like this:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
This ensures all HTTP traffic is redirected once, cleanly, to HTTPS.
At the same time, the HTTPS block must not contain any redirect back to HTTP. That would immediately create a loop.
Handle www and non-www Without Conflict
Another frequent issue is domain inconsistency. If both versions of the domain try to redirect each other, the browser will never settle.
We must choose one canonical version and stick to it.
For example, if we decide to use non-www:
- Redirect all www traffic to non-www
- Serve the application only on non-www
Example:
server {
listen 80;
server_name www.example.com;
return 301 https://example.com$request_uri;
}
The HTTPS server block should only define example.com, with no reverse redirect present anywhere.
Align Application-Level Redirects
Modern frameworks often include built-in redirect logic. While this is useful, it becomes a problem when Nginx is already handling the same responsibility.
For example:
- Django may enforce HTTPS using
SECURE_SSL_REDIRECT - WordPress may redirect based on site URL settings
- Node applications may include forced HTTPS middleware
If both Nginx and the application attempt to enforce HTTPS, they can easily conflict. The clean approach is to let Nginx handle redirects and ensure the application trusts that configuration.
Configure Reverse Proxy Headers Correctly
When Nginx is acting as a reverse proxy, missing headers can confuse the backend into thinking the request is still HTTP. The application then tries to redirect to HTTPS again, creating a loop.
To prevent this, we include:
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
The X-Forwarded-Proto header is especially important, as it tells the application whether the original request was HTTP or HTTPS.
Check CDN or Load Balancer Behavior
If a CDN like Cloudflare or a load balancer is involved, it may also be handling SSL and redirects. Misalignment here is a classic cause of loops.
A common example:
- CDN set to “Flexible SSL”
- Nginx forces HTTPS
This creates a cycle where traffic is repeatedly downgraded and upgraded.
The correct approach is to use “Full” or “Full (Strict)” SSL modes so that both layers agree on HTTPS handling.
Clear Cache and Reload Nginx
Redirects are heavily cached by browsers, so even after fixing the configuration, the issue may appear to persist.
We resolve this by:
- Testing in an incognito window
- Clearing browser cache
Then reload Nginx:
sudo systemctl reload nginx
Use Logs for Final Verification
If the issue is still unclear, logs provide direct visibility into what is happening.
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log
We look for repeated requests and status codes like 301 or 302 that indicate a loop.
Summary
ERR_TOO_MANY_REDIRECTS is rarely caused by a single mistake. It is usually the result of overlapping logic across multiple layers. The most effective fix is to simplify the setup, define one clear redirect strategy, and ensure every component follows it.
A stable configuration is not about adding more rules. It is about removing unnecessary ones and making each layer behave predictably.