Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteiTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Need a server to try this on? Antihost offers Linux VPS plans with NVMe storage, full root access and a 14-day free trial.
For hundreds of fixed URL changes, keep the redirects in an http-context map and load the entries from a separate file. Use return 301 for each resolved destination, reserve rewrite for genuine patterns, and test every response’s status and Location header before releasing the change.
The maintainable design for a large redirect list
A large redirect project becomes manageable when configuration logic and redirect data are separated. Nginx’s map directive provides the lookup table, while an included file stores one old-to-new mapping per line. The map must be declared in the http context; the server that receives the legacy requests then uses the resulting variable.
Recommended Free Tools
This arrangement avoids hundreds of nearly identical directives in a server block. It also gives reviewers a small, data-oriented file to inspect, regenerate, and validate. Nginx evaluates variables lazily: declaring even a large map does not add request-processing work until the mapped variable is actually used.
http {
map $request_uri $redirect_target {
default "";
include /etc/nginx/redirects.map;
}
server {
listen 80;
server_name old.example.com;
if ($redirect_target != "") {
return 301 https://www.example.com$redirect_target;
}
}
}
The example uses an empty string as the miss value. Requests that have no entry continue through the normal server behavior, while a match receives a permanent redirect. If your map values are already complete destination URLs, the server can instead issue return 301 $redirect_target;. Confirm the chosen variable and URL form against the Nginx version running in production before rollout.
#1 Best Overall
Build the included redirect table
Use one exact mapping per line
Create /etc/nginx/redirects.map (or another path readable by the Nginx master process) with a source URI followed by its destination and a semicolon:
/old-product /products/new-product;
/legacy/about https://www.example.com/about;
/archive/2019-report /reports/annual-report;
The first field is matched against the variable named in the map. In the configuration above that variable is $request_uri. A relative value such as /products/new-product is appended to the destination host in the return statement. An absolute value such as https://www.example.com/about can be returned directly when the map is used as a complete-URL table.
Keep data generation separate from Nginx syntax
Generate the file from a reviewed export, spreadsheet, or migration database rather than hand-editing hundreds of lines. The generator or review process should:
- Reject duplicate old paths instead of silently choosing one destination.
- Normalize the intended leading slash and trailing-slash policy.
- Validate that every destination is either an allowed relative path or a complete URL in the format your configuration expects.
- Flag destinations that point to another legacy path, which creates a redirect chain.
- Preserve a deterministic sort order so changes are easy to review.
Do not put comments, commas, or JSON syntax into the data file unless your generator converts them into valid Nginx map entries. A malformed included file causes the whole configuration test to fail, which is preferable to silently deploying a partial list.
How Nginx chooses a map entry
Map matching is not simply “first line wins.” Nginx gives exact string keys priority over masks, then considers regular expressions in their listed order, and finally uses default when nothing matches. This matters when a broad pattern and a specific legacy URL overlap.
| Match type | Example | Selection behavior | Best use |
|---|---|---|---|
| Exact string | /old-product |
Wins over masks and regular expressions | Individual URL migrations |
| Mask or prefix-style key | Configured map mask | Considered after exact strings | Grouped paths when a mask is truly appropriate |
| Regular expression | ~^/old-section/(.*)$ |
Evaluated in the order written | Patterned transformations with captured parts |
default |
default ""; |
Used when no other key matches | Explicit miss behavior |
Put exceptions in the table as exact entries and keep broad expressions below them. Although exact keys have precedence, regex ordering still determines which expression wins when several expressions match. Treat the order of regex entries as part of the behavior, not as formatting.
Free tools Windows power users keep installed
One-click scans. No signup required.
Rank #2
Choose between return and rewrite
| Mechanism | How it matches | Use it for | Main risk |
|---|---|---|---|
return 301 |
Sends a specific status and destination immediately | Fixed mappings, host migrations, and map lookups | Incorrect destination construction or an overly broad condition |
rewrite |
Applies a regular expression and can substitute captures | Many URLs that share a verified structural pattern | Rule order, repeated location processing, loops, and accidental matches |
Fixed destinations: prefer return
Nginx documents return as the direct way to send a chosen redirect code from server or location context. With a map, the condition only fires when a destination was found:
if ($redirect_target != "") {
return 301 https://www.example.com$redirect_target;
}
This limited form of if contains only a comparison and a return, making the control flow explicit. If the map stores complete URLs, the equivalent is:
if ($redirect_target != "") {
return 301 $redirect_target;
}
Use the exact form that your Nginx release accepts and test it with nginx -t; a relative path and a complete URL are not interchangeable in every configuration.
Patterned changes: use rewrite deliberately
A regex is justified when the old and new paths have a real one-to-one structure. For example, a section whose final slug is unchanged can be transformed with a captured suffix:
rewrite ^/old-section/(.*)$ /new-section/$1 permanent;
Rewrite directives execute sequentially in configuration order. Place narrow exceptions before broader rules, and inspect every capture for empty or unexpected values. Do not use a pattern merely to avoid listing a few unrelated URLs; explicit map entries are easier to audit and less likely to redirect a URL that was never intended to move.
Host migrations belong in a separate server block
When the old hostname must redirect regardless of path, define a dedicated server for that host rather than embedding host tests inside path logic. Nginx’s conversion guidance describes this as the right way to handle a host migration:
server {
listen 80;
server_name example.org;
return 301 http://www.example.org$request_uri;
}
Keeping the old host separate prevents the canonical host from matching its own migration rule. It also makes the purpose of the block obvious during review. If path-specific redirects and a host migration are both required, decide which server receives the request first and keep each responsibility in its corresponding server block.
Decide whether the key is $request_uri or $uri
The map key determines whether query strings and normalization affect matching:
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstall$request_uricontains the original request path together with its arguments. A request such as/old-product?ref=mailtherefore has a key that includes the query string.$uriis Nginx’s normalized URI variable. It does not represent the original request line in the same way and is commonly used when the mapping should ignore the query string.
Choose one intentionally. If every query-string variant of an old page should map to the same destination, key the map on $uri and verify how the redirect should handle arguments. If tracking parameters or application arguments must be preserved, test the $request_uri behavior with real examples. Do not assume that a path entry automatically matches a request containing a query string when the map key includes the original arguments.
Trailing slashes, case, and encoding
Exact keys distinguish the strings you configure. Decide whether /guide and /guide/ are separate sources, then add explicit entries or a carefully bounded pattern. Treat case sensitivity as a policy decision rather than relying on a browser or upstream application to normalize it.
Percent-encoded characters are another source of surprises. Test both the encoded request and the destination that Nginx actually evaluates. A map based on $request_uri sees the original form, while a normalized variable can present a different representation. Keep encoded slashes and reserved characters out of broad regexes unless you have verified their behavior on the deployed version.
Prevent chains and redirect loops
Point directly to the final canonical URL
A chain such as /a -> /b -> /c makes clients and crawlers perform extra requests and leaves more opportunities for a later rule to break. Resolve the migration source list so /a points straight to /c whenever that final destination is known. The same review should flag destinations that are still legacy URLs.
Rank #4
Keep the canonical host out of legacy rules
A host rule that catches both the old and new host can redirect a request back to itself. Verify the server_name on every redirect block and send a request to the intended canonical hostname, not only to the old one.
Respect the rewrite cycle limit
Rewrite processing can trigger another location selection. Nginx limits rewrite cycles to 10; a configuration that keeps rewriting the same request can end in a 500 error. A loop can be caused by two opposing expressions, a pattern that matches its own destination, or a host rule that runs again after the path changes. Test the final path and host, not just the first response.
Deploy the table safely
- Freeze and review the source list. Record the old path, intended final URL, owner, and reason for each change. Reject duplicate old paths and unresolved destinations before generating the map.
- Generate the included file. Write valid Nginx entries with a semicolon on every line. Keep the generated file in the same deployment artifact as the configuration that includes it.
- Check permissions and path names. Ensure the Nginx master process can read the file and that the path in
includeexactly matches the deployed location. - Run the syntax test. Execute
nginx -t. This validates the main configuration and included files without replacing the active worker configuration. - Reload through the normal service manager. Use your operating system’s established Nginx reload procedure only after the test succeeds. A reload applies the new configuration while allowing existing workers to finish.
- Verify from a client. Check status and
Locationheaders for representative URLs before declaring the migration complete.
Do not edit the live file and immediately reload without a reproducible source and review trail. A syntax-valid map can still contain a wrong destination, a chain, or a rule that captures more URLs than intended.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Test status codes and Location headers
A browser hides too much information for redirect validation. Use a header-only request so the status and destination are visible:
curl -I http://old.example.com/old-product
For a successful permanent redirect, confirm that the response is 301 and that Location is the expected final URL. Follow redirects separately when checking for chains:
curl -I -L --max-redirs 10 http://old.example.com/old-product
Run tests against the exact host and scheme that users will request. A request to a different virtual host can exercise a different server block and produce a misleading result.
Minimum test matrix
| Case | What to verify |
|---|---|
| Exact mapped path | Status is 301 and Location is the intended final URL |
| Unmapped path | It follows the documented miss behavior rather than redirecting unexpectedly |
| Query-string request | Arguments are preserved, discarded, or transformed exactly as designed |
| Trailing-slash variant | The configured slash policy is applied consistently |
| Encoded path | Percent-encoding does not select the wrong entry or create a loop |
| Old hostname | The dedicated host block points to the canonical host and does not match it again |
| Already-canonical URL | No redirect rule catches the final URL |
| Pattern boundary | URLs just inside and outside a regex are handled correctly |
For hundreds of entries, automate these checks from the same reviewed source list. Fail the check when a response has the wrong status, a missing Location, an unexpected host, or more redirects than your policy permits.
Observe the rollout and diagnose failures
Sample access logs immediately after reload. Look for unexpected 3xx sequences, 404 responses at new destinations, requests that repeatedly hit the same legacy path, and traffic to a host that should have been retired. Keep enough request and response information to correlate the source URL with its redirect target while respecting your site’s privacy policy.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Common symptoms and fixes
- The map never matches. Check whether the key is
$request_urior$uri, including query strings, encoding, and the leading slash. Confirm the included file is actually loaded by the active configuration. - The wrong destination wins. Look for an exact entry, a broad mask, or an earlier regular expression that has precedence. Move exceptions into exact keys and reorder regexes from narrowest to broadest.
- The redirect loops. Compare the destination with every source key and host rule. Remove rules that match their own output and point intermediate URLs directly to the final canonical address.
- Nginx returns 500 during rewriting. Investigate repeated rewrite cycles and patterns that re-enter location processing. The rewrite module’s cycle limit is 10.
nginx -tfails. Inspect the reported line and the included file for a missing semicolon, an invalid quote, an unreadable path, or a destination syntax not supported by the deployed version. Do not reload until the test passes.- The header is correct but the page is wrong. A 301 only selects the destination. Check the destination application’s routing and its own status separately; a redirect can be correct while the new URL returns 404.
Maintain the redirect system after launch
Keep the generated map under version control with the source data and the Nginx configuration that consumes it. Review additions for duplicates, chains, and accidental host changes. When a product or section moves again, update the original source to the newest final URL instead of stacking another hop.
Retain a small set of automated probes for high-value URLs and run them after every map change. Periodically sample logs for old paths that still receive traffic and for new paths that return 404. Remove a mapping only when you have evidence that the old URL no longer needs to be preserved and your retention policy permits that change.
This design scales because the redirect data remains a simple included table, matching behavior is explicit, and deployment is guarded by syntax tests and header-level verification. Fixed entries stay in the map with return 301; only genuine structural transformations need ordered regular-expression rewrites.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

