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.

Atomic redirect swap A symlink repoints from the broken redirect map to the previous known-good map, the config is validated and reloaded, then the edge cache is purged. Atomic Redirect Swap 1. Repoint link 2. Validate 3. Reload 4. Purge edge ln -sfn prev map nginx -t systemctl reload CDN purge API Reload is zero-downtime; a failed validation aborts before any traffic shifts.
The swap repoints a symlink to the previous map, validates, reloads with no dropped connections, then purges the edge.

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 configtest pass 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.

The atomic redirect swap and what each gate prevents Four sequential steps — symlink repoint, config validation, graceful reload, and edge purge — each annotated with the specific failure it prevents if performed, and the consequence of skipping it. Four steps, each preventing one way the fix becomes the fault 1. ln -sfn one atomic operation 2. nginx -t gate, not a formality 3. reload not restart 4. purge edge then verify MISS skip it and traffic reads a half-written file skip it and a syntax error takes routing down entirely restart instead and in-flight requests are dropped skip it and the edge keeps serving the broken Location header The whole sequence runs in seconds — its value is entirely in the fact that none of the four steps can be improvised.
Step 2 is the one under most pressure to skip, and the only one whose omission can leave you with neither the old routing nor the new.

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-path resolves to the correct target in a single hop with no loop.
  • curl -sI https://www.example.com/category/ | grep -i cf-cache-status shows MISS then HIT after 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.

Where a broken redirect survives after the origin is fixed Three caching layers holding a broken 301: the origin which you fix directly, the CDN edge which a purge clears, and the browser cache which cannot be cleared remotely and outlives both. Fixing the origin clears one of three copies Origin config — fixed by the swap CDN edge — cleared by the purge Browser cache — cannot be cleared remotely seconds minutes until it expires you control it API call nothing you can do This is the argument for serving 302 rather than 301 while a mapping is still provisional — a temporary redirect that turns out to be wrong is forgotten in minutes; a permanent one that turns out to be wrong follows your users around for months. Promote to 301 once the destination is proven, not before.
The bottom row is why redirect faults are worth catching in staging: it is the one layer no rollback procedure can reach.

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 Location header) 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

← Back to Migration Rollback Playbooks

Explore Sub-topics