Redirect Rollback & Recovery
Context
When a new redirect map sends traffic into loops, dead ends, or the wrong targets, you need to restore the previous routing layer in seconds without dropping a request. This guide covers reverting redirect maps and rules through atomic config swaps, restoring the previous server configuration, and purging the edge caches that would otherwise keep serving broken routes. It runs under Migration Rollback Playbooks and reverses changes deployed via URL Mapping & Redirect Architecture.
The reason this rollback is worth treating as its own procedure, rather than folding it into the DNS one, is that it is the fast path. A redirect fault lives entirely in the HTTP layer, which you control completely and which has no cache you cannot flush on demand. Recovery is measured in seconds rather than in TTL cycles, and it costs you nothing in propagation. Reaching for a DNS rollback to fix a routing bug is the single most common way teams turn a thirty-second fix into a thirty-minute one.
That speed only exists if the previous map is a file you can point at. The whole design below — indirection, archived config, validation gate — is arranged so the reversal is a swap rather than a reconstruction, because reconstructing a redirect map under pressure means re-deriving rules from a mapping inventory while traffic is failing, and that is not a rollback in any useful sense.
Pre-flight Checks
Keep the previous routing layer archived and ready so reversion is a swap, not a rebuild.
- Archive the previous redirect map and server config under version control, tagged to the last verified state.
- Confirm the live config references the map via an indirection (symlink or
include) so swaps are atomic. - Verify
nginx -t/apachectl configtestpass on the archived config before you need it. - Confirm CDN purge credentials and the exact paths or tags to invalidate, and check the credentials belong to a role the on-call engineer actually holds rather than to the person who set the CDN up.
Redirect Rollback Readiness Checklist:
Execution Steps
Swap the routing layer atomically, reload without downtime, then clear stale edge state.
1. Repoint to the Previous Map Atomically
Use a symlink swap (ln -sfn) or activate the archived include so the server reads the previous known-good map in a single filesystem operation. Editing the live map in place risks serving a half-written file to live traffic. Confirm the restored rules match the last verified state in URL Mapping & Redirect Architecture.
Make sure the indirection actually exists before you rely on it. The pattern only works if the live configuration references the map through a symlink or an include whose target you can repoint — if the rules are written directly into the server block, there is nothing to swap and the reversal degrades into editing a live file, which is precisely what the design avoids. Establish the indirection as part of building the redirect layer, not as part of preparing to roll it back, and verify by repointing to an identical copy and reloading: if that is a no-op, the mechanism works.
2. Validate Before Reload
Run nginx -t or apachectl configtest so a syntax error aborts the rollback before it can take down the routing layer. A failed validation must stop the process — never reload an unvalidated config during an incident. This gate is what makes the swap safe to run under pressure.
Note what the validation does and does not cover. nginx -t proves the configuration parses and that referenced files exist; it says nothing about whether the rules are correct. A map full of syntactically perfect redirects pointing at the wrong destinations passes cleanly. That is fine — this gate exists to stop the rollback from crashing the routing layer, not to verify routing logic, which is what the archived map’s own prior verification is for. Do not let a green configtest substitute for the post-reload spot check.
3. Reload With Zero Downtime
Apply the config with systemctl reload nginx or apachectl graceful, both of which finish in-flight requests on old workers while new workers pick up the restored rules. A hard restart drops connections and worsens the incident. Reload, then immediately spot-check a known-broken path.
Spot-check a path you know was broken, not a path you know works. The instinct after any reload is to confirm the homepage still loads, which tells you the server survived and nothing about whether the fault is fixed. Keep a short list of the specific URLs that triggered the rollback — the looping path, the wrong destination, the 404 — and curl those first. They are the only evidence that the swap achieved anything.
4. Purge the Edge Cache
Redirect responses are cacheable, so the CDN may keep serving the broken Location header after the origin is fixed. Purge the affected paths or cache tags via the provider API, then confirm a MISS followed by a correct HIT. Coordinate the purge timing with the recovery broadcast in Migration Rollback Playbooks, and use trigger conditions from Rollback Trigger Thresholds to decide when to fire.
The four steps have a strict order, and each exists to prevent a specific way the reversal can itself become the outage.
Configs / Commands
Each pairing below is deliberately a single line of shell with an && between the validation and the apply, so the gate cannot be forgotten or run separately. Store them as a script in the migration branch rather than as documentation to be retyped — the goal is that the reversal is one command whose correctness was reviewed on a calm afternoon.
Nginx — atomic map swap, validate, reload:
# Repoint the active map to the archived known-good version, then reload safely
ln -sfn /etc/nginx/maps/redirects.prev.conf /etc/nginx/maps/redirects.active.conf
nginx -t && systemctl reload nginx # reload finishes in-flight requests, no drops
Apache — restore prior rewrite config gracefully:
# Activate the archived rules, test syntax, then graceful restart
a2disconf redirects && cp /etc/apache2/conf-available/redirects.prev.conf \
/etc/apache2/conf-available/redirects.conf
a2enconf redirects && apachectl configtest && apachectl graceful
The Apache sequence has one more moving part than the Nginx one because a2disconf and a2enconf manipulate symlinks in a different directory than the file copy does. If you run Apache, consider restructuring so the rollback is a single a2enconf of a permanently-present previous configuration rather than a copy followed by an enable — fewer operations between “decided to revert” and “reverted” is the only optimisation that matters here.
Cloudflare API — purge cached redirect responses:
# Purge specific URLs so the broken Location header is no longer served from edge
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE/purge_cache" \
-H "Authorization: Bearer $CF_TOKEN" -H "Content-Type: application/json" \
--data '{"files":["https://www.example.com/old-path","https://www.example.com/category/"]}'
Prefer a targeted purge to a zone-wide one where you can. Purging everything is tempting under pressure and usually works, but it also evicts every cached asset on the site simultaneously, sending the full weight of your traffic to an origin that is already having a bad day. On a large site that turns a routing incident into a capacity incident. Purge the affected paths or cache tags first, verify, and escalate to a full purge only if targeted invalidation demonstrably fails to clear the broken responses.
Reverting the smallest thing that fixes the fault is the whole discipline — Rolling Back a Broken Redirect Map Safely works through the segment-level revert and the cache purge order, and Restoring Redirect Rules from Version Control handles the case where the repository is not a complete record of what is served.
Validation
Prove loops are gone, targets are correct, and the edge serves fresh responses.
curl -sIL https://www.example.com/old-pathresolves to the correct target in a single hop with no loop.curl -sI https://www.example.com/category/ | grep -i cf-cache-statusshowsMISSthenHITafter purge.- A crawl of the top traffic paths returns no new 3xx chains or 404s versus the pre-migration baseline.
- 4xx rate returns below the ceiling defined in Rollback Trigger Thresholds.
Cached redirects are the part of this that surprises people, because a redirect feels like an instruction rather than content. It is not: a 301 is one of the most aggressively cached responses on the web, held by CDNs, by intermediate proxies, and — most stubbornly — by browsers, which will honour a cached permanent redirect without contacting the network at all.
Run the loop check across a list of paths rather than one at a time. curl -sIL on a single URL confirms that URL; what you need after a rollback is confidence across the route classes that changed, which means a scripted pass over a sample drawn from each — a few product pages, a few category pages, a few legacy paths that should now redirect, and a few that should legitimately 404. Compare the resulting status-and-destination pairs against the pre-migration crawl rather than eyeballing them, because the failure you are looking for is a path whose destination changed subtly rather than one that errors outright.
Rollback Triggers
Fire the redirect rollback when routing faults breach these limits.
- Redirect loops: any path exceeding 2 hops or returning a loop fires an immediate swap to the previous map.
- 4xx spike: 4xx rate above baseline + 10 points sustained for 10 minutes signals broken targets.
- Wrong targets: confirmed mismatches on top-traffic URLs (wrong
Locationheader) trigger reversion. - Stale edge: if a purge fails to clear broken responses, escalate to a zone-wide purge before standing down.
FAQ
Why use a symlink swap instead of editing the live redirect map? A symlink repoint is a single atomic filesystem operation, so the server never reads a partially written file. Editing the live map in place can expose live traffic to an inconsistent rule set mid-save, which is exactly the kind of second fault you cannot afford during a rollback.
Does systemctl reload drop any in-flight requests?
No. A reload starts new worker processes with the restored config while existing workers finish their current requests, then exit. This is why you reload rather than restart during a rollback — a hard restart would terminate active connections.
Why do I need to purge the CDN after fixing redirects at the origin?
Redirect responses carry cacheable status codes, so the CDN may keep returning the broken Location header from its edge nodes even after the origin is corrected. A targeted purge of the affected paths forces the edge to re-fetch the fixed response.
Can I roll back redirects without touching DNS? Yes, and you often should. Redirect faults live entirely in the HTTP routing layer, so an atomic config swap plus a cache purge fixes them without the TTL-bound wait that a DNS rollback incurs. Reserve DNS rollback for origin-level failures.
How do I make sure the archived map really is the last known-good one?
Tag it at the moment it was verified, not at the moment it was replaced. The common failure is an archive taken as a side effect of the deploy — cp redirects.conf redirects.prev.conf executed just before overwriting — which captures whatever was live, including any changes made since the last verification. Instead, tag the map in version control when the crawl confirms it produces no chains and no unexpected 404s, and have the rollback point at that tag. Then the artefact you revert to is one you have evidence for.
Should the rollback restore the whole server config or only the redirect map? Only the map, if the indirection allows it. A narrow reversal has a much smaller blast radius: restoring an entire server config drags along every unrelated change made since the archive — a TLS setting, a header, a rate limit — and any of those could introduce a second fault while you are recovering from the first. Structure the config so redirects live in their own included file precisely so this reversal can be surgical.
What if the purge succeeds but users still report the old redirect?
That is almost always the browser cache, and it is the one layer no purge reaches. Confirm by requesting the path in a private window or with curl, which bypasses the browser store — if those return the corrected response, the origin and edge are both fixed and the remaining reports will decay as cached entries expire. Where the mis-issued redirect was a 301 with a long lifetime, the only real mitigation is to keep the erroneous destination serving a corrective redirect back, so users carrying the bad cache entry still end up in the right place.
Can this rollback be automated end to end? The swap, validation, reload and purge all script cleanly, so the mechanical part can be a single command — and it should be, because a four-step sequence executed by hand under pressure is a four-step sequence with a typo in it. What should stay manual is the decision to run it. Automating the trigger for a redirect rollback is riskier than for an origin failure, because the symptoms — a 4xx rise, an unexpected chain — also occur transiently during legitimate cache warm-up. Script the execution, keep a human on the invocation.
How does this interact with a redirect layer at the CDN rather than the origin? The same shape applies but the artefacts move: the “previous map” is a versioned rule set in the provider’s configuration rather than a file on disk, and the atomic swap is an API call that activates a prior ruleset version. Confirm before the migration that your provider supports versioned rulesets and rollback to a previous version, because some redirect-rule products only offer edit-in-place — in which case you need to export the current rules as a restorable artefact yourself before making changes, exactly as you would archive a config file.
How long should the previous redirect map stay archived? Until the migration has cleared its full soak window and a crawl of the new routing has come back clean — then keep it in version control indefinitely, but stand down the active indirection. The reason to formally retire it is the same as for any staged rollback asset: an archived map that has silently diverged from anything the site has ever served is a trap, because the next person to reach for it during an unrelated incident will restore routing that predates six months of subsequent changes. Tag it with the date and the migration it belongs to, and remove the symlink target once the migration is declared complete.
What if the fault is in a small number of rules rather than the whole map? Swap the whole map anyway. Editing out the offending rules is a smaller change in principle and a much larger risk in practice, because it produces a configuration that has never been verified as a unit — you are hand-authoring a new routing state during an incident and hoping it is correct. The archived map, whatever its other shortcomings, is a state the site demonstrably ran on. Revert wholesale, confirm recovery, and then fix the specific rules properly in the next deploy where the change can be reviewed and crawled before it ships.
Related
- URL Mapping & Redirect Architecture
- Rollback Trigger Thresholds
- DNS Rollback Procedures
- Redirect Chain Elimination
← Back to Migration Rollback Playbooks