ORIGINAL REDDIT POST

How to undo a permanent redirect?

Some time ago I moved a page from Nextjs to a Wordpress site and added a permanent redirect to the subdomain, like so site.com/page --> page.site.com At the time I thought this would be permanent, but now we would like to switch it back. I had also naively…

Original postr/webdev

Some time ago I moved a page from Nextjs to a Wordpress site and added a permanent redirect to the subdomain, like so site.com/page --> page.site.com At the time I thought this would be permanent, but now we would like to switch it back. I had also naively thought that permanent meant more like semi-permanent and the browser would at least occasionally double check that the redirect is valid. That seems to not be the case (at least on chrome) and I am still getting a 308 Permanent Redirect (from disk cache) to the subdomain at least a week after the redirect was removed. Obviously another redirect back to the new path would cause a loop and the only solution I can think of is to change to a new path like site.com/page2 and implement a redirect from page.site.com. Is there some solution I am not aware of?

Collected discussion

25 comments

u/vanquish349

do the redirect loop, chrome won't believe it and will refetch the original content to confirm and in process will invalidate the cache.

u/qascevgdOP

Got any source for this?

u/vanquish349

I've done it a bunch of times, I read about it a while ago and it seemed to work well at the time. I just tried finding the source for just then and can't find anything. Which has got me a bit worried. Might be talking shit.

u/vanquish349

The tests I ran all seemed to work, but they weren't very rigourous. I would also doubt it would be in spec too. but what curl be useful here for? to make sure you set the redirect up?

u/nerd_rage218

This is the one. From the browser side a 301 or 308 is basically write once, so 302 until you are certain and promote it later. Costs almost nothing and avoids exactly this.

u/tswaters

I don't even think there's a benefit to permanent redirects? Maybe the 500 byte response the server spits out once & and gets cache. It's one of those things during a PR where someone needs to do a really got job of explaining why a regular redirect won't work.

u/thekwoka

well, yeah, cause they do a 301 so that it IS cached...so they don't send cache headers... But it would be smart to split the difference and even if you think you want permanent, to set a reasonably short enough age, like one week. But then again, we also know none of the things we work on get people visiting them that often anyway.

u/tswaters

That's the neat thing, you don't! Anyone that was redirected will continue to be until they clear their cache. Never serve a permanent redirect unless you are absolutely sure.

u/ryaaan89

This is the kind of internet dark arts shit I’m on Reddit for.

u/Soft_ACK

This is why I never serve a perma redirect, because of these issues.

u/nakfil

I’ve seen this work many times as well

u/void-wanderer-

As you have learned, a permanent redirect cannot easily be reverted. The good thing is, you control target page.site.com. If you wouldn't, you would be shit out of luck. Usually you can redirect back to site.com/page?some-parameter=1. A "too many redirects" won't trigger for 2 redirects. And as site.com/page?some-parameter=1 is not the same as site.com/page, it will have another redirect cache key and should resolve. Use this header for your subdomain site (302!): HTTP/1.1 302 Found Location: https://site.com/page?some-parameter=1 Cache-Control: no-store Also, before starting tinkering, make sure you have the redirect cached in as many browsers and computers as possible, so you can verify that the solution really works.

u/Soft_ACK

I wish this was true, but I've done this before and didn't work, and the problem is Chrome sometimes cache the whole thing through cross profile (meaning all other chrome profiles) and you would have to test from another browser (or good old `curl`) just to confirm if you did the right thing.

u/AlwaysHopelesslyLost

It was a 50/50 whether the top comment would be this or that stupid meme of the guy with his hand on the other guys shoulder lol

u/writtenweb

Add ?breakcache or whatever to the second reversing redirect, as someone else said above. This is the way!

u/AwaySky5696

The 308s get cached by the browser indefinitely — that's the "permanent" part. Removing the redirect server-side won't help users who already have it cached. The easiest fix is to add a new redirect from page.site.com back to site.com/page using a 302 (temporary), so cached clients still land in the right place.

u/Fluffy-Bus4822

You can't. That's why I almost never do it. Because if you make a mistake you're fucked.

u/Alex_SQSP

The query string workaround mentioned above sounds like the safest option to test. It keeps the original page in place while giving the browser a slightly different URL to load, which may get around the cached redirect. Another commenter suggested forcing a redirect loop, I wouldn’t trust the redirect loop trick in production. Even the person who tested it needed quite a few loops before Chrome checked again, which feels a bit too unpredictable. Keep one browser with the old redirect cached while testing so you can confirm the fix works for someone already stuck in that state.

u/kaelwd

You could try a script on page.site.com that does a fetch: fetch('https://site.com/page', { cache: 'reload', redirect: 'manual', }).then(res => { if (res.type === 'opaqueredirect') { // redirect still exists for some reason, fall back to query string location.href = 'https://site.com/page?nocache' } else { location.href = 'https://site.com/page' } })

u/Loud_Coyote1594

One thing worth doing on whatever redirect you deploy next: 301 and 308 responses can carry their own Cache-Control header. Send Cache-Control: no-store (or max-age=0, must-revalidate) alongside it and browsers won't pin it indefinitely. Most frameworks and hosts don't set anything by default, which is exactly how people end up where you are. Doesn't help with the clients that already cached the old one, but it stops the reverse redirect you're about to ship from becoming the same trap in six months. The other side nobody's mentioned: Google has almost certainly consolidated the canonical over to page.site.com by now. When you flip it back, make sure the canonical tag on the restored page points at site.com/page, otherwise the redirect says one thing and the canonical says another and it sits in limbo for weeks. If you go the ?breakcache route, put a canonical on that version too or you'll end up with the query-string URL indexed.

u/bkocdur

You can undo it without renaming the page. The trick is that browsers cache redirects per exact URL, so you break the loop by making the reverse redirect target a URL the browser has never cached. Setup: serve site.com/page normally again (200), and on the subdomain redirect page.site.com back to site.com/page?src=sub (any harmless query param works), which then serves the page. Walk through what happens to a returning visitor with the poisoned cache: they hit site.com/page, the browser replays its cached 308 to page.site.com, your server 301s them to site.com/page?src=sub. That URL was never redirected, so there is nothing cached for it: they get a 200 and see the page. No loop, because the loop required the destination to be the exact cached URL, and the param makes it a different one. Cleanup: put a canonical tag on the page pointing at the clean site.com/page so the param variant never competes in search, and keep the param redirect for a few months. New visitors never touch the subdomain, and the poisoned caches age out or get overwritten gradually. Eventually you can point the subdomain redirect at the clean URL. Two things worth knowing for next time: Chrome treats a 308/301 without explicit cache headers as cacheable for a very long time, effectively forever in practice. If you ever want an "undoable" permanent redirect, send it with Cache-Control: max-age=86400 or so. You keep the SEO semantics and a browser rechecks daily. Use a 302/307 until you are genuinely sure. The old advice that permanent redirects pass more link equity than temporary ones is outdated; Google treats a long-lived 302 fine. The asymmetry is real though: a 302 upgraded to 308 later costs nothing, while a 308 you regret costs you this exact thread. Google itself is not your problem, by the way. It recrawls and updates redirects without the browser-style cache. This is purely a returning-visitor problem, and the query param handles them.

u/thekwoka

Realistically, with time it will switch back. It's not really as much of a "permanent" thing as in "until they clear cache". The browser will be aware of it but also decide to try anyway. A forced redirect of the page.site.com to the site.com/page should also make the browser check it, not just assume circular redirects.

u/Buinsoft_Tech

Worth noting this is fairly Chromium specific, Firefox and Safari cache 301/308 far less aggressively and mostly respect normal HTTP cache headers instead of treating a permanent redirect as forever. If you control the response, adding an explicit Cache-Control: no-store on any future redirects avoids this entirely, Chrome's aggressive caching mainly kicks in when there is no directive telling it otherwise.

u/pdfops

Yeah that's the classic 301/308 cache poisoning trap. Chromium caches permanent redirects at the HTTP cache layer keyed by URL and ignores Cache-Control/Expires on the redirect response itself, so pulling it server side does nothing for browsers that already hit it once. New path is really the only reliable fix for existing visitors. Lesson for next time: use 302/307 for anything that might change, save 301/308 for redirects you're actually sure are forever.