UTM codes trigger ERR_TOO_MANY_REDIRECTS when not in alphabetical order

We recently enabled Cloudflare’s proxy and Robot Fight Mode on our primary domain, using a free account, but now we’re having problems with links containing UTM codes in the query string.

It appears that Cloudflare is rearranging the variables in query strings so they’re in alphabetical order. But if there are any UTM codes in the string, and it isn’t already in alphabetical order, then Cloudflare gets stuck in a redirect loop and the browser throws a ERR_TOO_MANY_REDIRECTS error. They don’t even need to be real UTM codes, as long as they start with utm_, so utm_fake can trigger the error.

As an example, this triggers the error:
https://californiasciencecenter.org/?utm_b=test1&utm_a=test2

…but this does not:
https://californiasciencecenter.org/?utm_a=test2&utm_b=test1

If I change the ‘m’ to ‘n’, like this:
https://californiasciencecenter.org/?utn_b=test1&utn_a=test2

…the page loads fine, but the query string is reorganized to this:
https://californiasciencecenter.org/?utn_a=test2&utn_b=test1

If I hit the same server using a subdomain that bypasses Cloudflare’s proxy, none of this happens and the page loads fine.

I’ve read all the other posts related to this error and none of them seem to apply. We’re not using any page rules, and our SSL/TLS encryption mode is Full.

When I use the Redirect Path extension in Chrome, this is what I see:

Status Code	URL	IP	Page Type	Redirect Type	Redirect URL	
301	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2	2606:4700:3035::ac43:a1f6	server_redirect	permanent	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2
301	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2	2606:4700:3035::ac43:a1f6	server_redirect	permanent	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2
301	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2	2606:4700:3035::ac43:a1f6	server_redirect	permanent	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2
301	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2	2606:4700:3035::ac43:a1f6	server_redirect	permanent	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2
301	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2	2606:4700:3035::ac43:a1f6	server_redirect	permanent	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2
301	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2	2606:4700:3035::ac43:a1f6	server_redirect	permanent	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2
301	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2	2606:4700:3035::ac43:a1f6	server_redirect	permanent	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2
301	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2	2606:4700:3035::ac43:a1f6	server_redirect	permanent	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2
301	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2	2606:4700:3035::ac43:a1f6	server_redirect	permanent	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2
301	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2	2606:4700:3035::ac43:a1f6	server_redirect	permanent	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2
301	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2	2606:4700:3035::ac43:a1f6	server_redirect	permanent	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2
301	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2	2606:4700:3035::ac43:a1f6	server_redirect	permanent	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2
301	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2	2606:4700:3035::ac43:a1f6	server_redirect	permanent	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2
301	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2	2606:4700:3035::ac43:a1f6	server_redirect	permanent	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2
301	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2	2606:4700:3035::ac43:a1f6	server_redirect	permanent	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2
301	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2	2606:4700:3035::ac43:a1f6	server_redirect	permanent	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2
301	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2	2606:4700:3035::ac43:a1f6	server_redirect	permanent	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2
301	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2	2606:4700:3035::ac43:a1f6	server_redirect	permanent	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2
301	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2	2606:4700:3035::ac43:a1f6	server_redirect	permanent	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2
301	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2	2606:4700:3035::ac43:a1f6	server_redirect	permanent	https://californiasciencecenter.org/?utm_b=test1&utm_a=test2

If I change ‘m’ to ‘n’ again, then I get this path:

Status Code	URL	IP	Page Type	Redirect Type	Redirect URL	
301	https://californiasciencecenter.org/?utn_b=test1&utn_a=test2	2606:4700:3035::ac43:a1f6	server_redirect	permanent	https://californiasciencecenter.org/?utn_a=test2&utn_b=test1
200	https://californiasciencecenter.org/?utn_a=test2&utn_b=test1	2606:4700:3035::ac43:a1f6	normal	none	none

That appears to be a Cloudflare IP, so this is really looking like a bug in Cloudflare, but if anyone has any brilliant ideas, I’m game to try anything.

What if the ideas aren’t brilliant? :joy: Here’s just some food for thought…

This is really strange. Your setup seems to include multiple origin/proxy caches, and I’m betting one of those services is somehow misconfigured not playing well with Cloudflare.

I noticed your origin is sending a Vary header with a value of Cookie. Cloudflare does ignore by default the Vary header for its own caching decision, except for the “Accept Encoding” value, but your origin may be using the cookie set by Bot Fight Mode to make their own caching decision. So, with Cloudflare you get one result, without it, you get another. (Cloudflare is not caching the HTML)

Also, in both the URL that results in a loop, and the other that redirects only once to sort the query string, if you check the headers of the request prior to the redirect, you’ll see a header that reads:

x-drupal-route-normalizer: 1

The same header is not present with the URL that returns a straight 200 response. Could this be a hint that Drupal is playing a role here?

1 Like

Yes! It is!!!

The culprit seems to be the Redirect module (https://www.drupal.org/project/redirect). Unchecking its Enforce clean and canonical URLs setting fixes the issue. I’m still not sure exactly what that setting is doing to cause this problem, and disabling it will no doubt cause other problems, but baby steps. At least now I know where to look. So, thank you @cbrandt ! It was a brilliant idea after all.

1 Like

Problem solved! The patch at https://www.drupal.org/project/redirect/issues/3037259 fixes the problem without disabling clean URLs.

1 Like

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.