Hosting Autopsy / The redirect loop nobody could see

The redirect loop nobody could see

HOSTING AUTOPSY

6 min read · 1,381 words

This is a composite case written by the editors. It is built from patterns that come up often in support work and is not the account of a particular named person or company.

A developer put a site behind a CDN to speed it up and switched on the CDN's setting for "flexible" encryption, which encrypts the connection between the visitor and the CDN but uses plain HTTP between the CDN and the origin server. The origin server, meanwhile, had a rule that redirected every plain HTTP request to HTTPS.

The result was a loop. The visitor asked for HTTPS, the CDN asked the origin over HTTP, the origin said "go to HTTPS", the CDN passed that back, the browser tried again. After a few rounds the browser gave up with a "too many redirects" error. The developer, who had previously tested the site by connecting directly to the origin, saw nothing wrong.

What made it hard was that the problem existed only on the path through the CDN. The fix was to change the CDN to a mode that connects to the origin over HTTPS and to install a valid certificate there. The scenario is a composite, a small training company whose site was being sped up before a course launch, and it is among the commonest redirect faults we see once a CDN or proxy is introduced.

Two good ideas that cancel out

Each setting on its own was reasonable. The CDN offered a quick way to get a padlock for visitors without touching the origin: terminate HTTPS at the edge, and talk to the origin in plain HTTP across the internet. That is the "flexible" mode. It is easy to switch on because the origin needs no certificate at all.

The origin, for its part, had been set up months earlier to force HTTPS. A rule in the web server, or in the application, said that any request arriving over plain HTTP should be answered with a 301 pointing at the same address on HTTPS. That is exactly what you want when visitors reach the server directly.

Put the two together and the origin never sees an HTTPS request. Every request that arrives from the CDN is plain HTTP, because that is what flexible mode does. The origin does its duty and redirects, over and over.

BrowserCDNOrigin1. GET https://2. GET http://3. 301 to https://4. 301 passed on5. GET https:// again...and so on, until the browser stops
The browser's request is always HTTPS and the origin's view of it is always HTTP, so the redirect never resolves.

What the developer saw

For the developer there was no symptom until a colleague reported it. The site worked when he browsed to the origin's address directly, because that path used the origin's own certificate and made the request over HTTPS in the first place. It also worked in the CDN's own dashboard preview, which does not follow redirects. He told the team the CDN was set up, and the team opened the live address.

The browser's message differs by vendor. Chromium-based browsers say the page "redirected you too many times" and give ERR_TOO_MANY_REDIRECTS. Firefox says the page isn't redirecting properly. Some visitors saw it, others, who had visited before and had cached redirects, saw odd behaviour. A few saw the old site because of cached DNS, which led to a lost hour while people disagreed about whether it was broken.

The mental trap is that every part tested alone was healthy. The origin was fine. The CDN was fine. The certificate at the edge was valid. The fault belonged to the combination, and only a test from a visitor's position, over the same route, shows a combination.

Diagnosing it with curl

The quickest tool is curl with the redirect-following option and a limit, so it stops rather than looping for ever:

curl -sIL --max-redirs 5 https://www.example.com/ | grep -iE '^(HTTP|location)'

A looping site prints something like this, with the same pair repeating:

HTTP/2 301
location: https://www.example.com/
HTTP/2 301
location: https://www.example.com/
HTTP/2 301
location: https://www.example.com/
curl: (47) Maximum (5) redirects followed

The tell is that the target is exactly the address you asked for. A redirect to itself can only repeat. To see what the origin thinks it is being asked, look at the origin's access log. In this case every request from the CDN's addresses arrived on port 80, and each got a 301.

The Location header is the first thing to read, and the status code reference explains 301 against 302. If you can, also compare the response headers of a request to the origin address with one through the CDN. Headers that identify the CDN, and any header naming the original scheme, tell you which hop produced the redirect.

Why it was missed before launch

There was a test plan, and it passed. It checked that the home page loaded, that the contact form submitted, and that the new certificate at the edge showed a padlock. All of that was done from the office, where the developer's machine had a hosts file entry from earlier work pointing the site's name at the origin directly. Every test therefore bypassed the CDN, and the CDN was the thing that had changed.

The lesson is a general one about adding layers. A proxy, CDN or load balancer changes what the origin sees: the client address, the scheme, sometimes the host name. Any rule at the origin that depends on those facts needs checking again. Redirects are the most obvious case, and they are also the one where a mistake locks everybody out rather than merely breaking a page.

The encryption modes, compared

Mode (generic names)Visitor to CDNCDN to originOrigin certificate needed
OffHTTPHTTPNo
FlexibleHTTPSHTTPNo
FullHTTPSHTTPS, certificate not verifiedYes, any
Strict or full-verificationHTTPSHTTPS, certificate verifiedYes, valid for the site's name

Naming differs between providers, so read the descriptions rather than the labels. What matters is the middle column. Flexible mode leaves the second leg of the journey readable to anyone between the CDN and the origin, which is often a long way over the public internet. The visitor sees a padlock and the data is not encrypted for its whole trip. That alone is a reason to avoid it for any site with logins or forms.

FlexibleVisitorHTTPSCDNHTTPOriginStrictVisitorHTTPSCDNHTTPS, verifiedOriginIn strict mode the origin sees HTTPS, so its redirect rule stays idle
In flexible mode the origin only ever sees HTTP; in strict mode it sees HTTPS and the redirect rule never fires.

The fix

  1. Install a valid certificate on the origin for the site's name. A free ACME-issued certificate is enough, and many hosting panels do it in a click.
  2. Confirm the origin answers properly over HTTPS on its own: curl -sI --resolve www.example.com:443:203.0.113.10 https://www.example.com/ should give a 200 without a certificate warning.
  3. Switch the CDN to the strict mode, which connects over HTTPS and verifies the certificate.
  4. Purge the CDN's cache, since a cached redirect response can survive the change.
  5. Re-run the curl test from outside, and open the site in a private window so the browser's cached 301s are not in play.

The loop stopped at once. The training company's launch went ahead the next day.

Some guides suggest keeping flexible mode and making the origin trust a forwarded-scheme header instead. That stops the loop, but it leaves the second leg unencrypted. Prefer fixing the origin certificate.

Common questions

Why did the browser say too many redirects and not something about security?

Because each response was a perfectly valid redirect. Nothing was insecure from its point of view, it just never reached a page.

Will clearing cookies help?

Occasionally, when the loop is caused by a cookie-based login redirect. Here it did not, because the loop was at the protocol level.

Do application plugins cause the same loop?

Yes. A "force HTTPS" setting in a CMS or plugin behaves like the server rule, and it too sees plain HTTP behind a flexible proxy.

Can the CDN redirect for me instead?

Yes, most can redirect HTTP to HTTPS at the edge. Doing it there and removing the origin rule is a clean alternative, but still use an encrypted second leg.

What would have caught it

PreviousThe contact form that blacklisted the serverNextThe disk that filled up overnight

More from Hosting Autopsy

Autopsy

The launch-day database that ran out of connections

A local theatre put tickets for its autumn season on sale at noon and announced it on social media a day...

Autopsy

The image that cost a month's hosting

A photographer on a pay-by-usage cloud plan published a picture that was picked up by a popular forum. People...

Autopsy

The sitemap that listed forty thousand junk URLs

A furniture retailer added a filter system to its catalogue: colour, material, price band, size. Each...