Recommended Free Tools
For hundreds of fixed URL migrations, the maintainable Nginx design is an http-context map backed by an included redirect file, with a dedicated old-host server block returning 301. Keep regular-expression rewrite rules for genuine URL patterns, not for a long list of unrelated paths.
Need a server to try this on? Antihost offers Linux VPS plans with NVMe storage, full root access and a 14-day free trial.
Build the table from a reviewed source list, test the configuration with nginx -t, then verify every representative redirect by checking both the HTTP status and the Location header. This catches wrong destinations, chains, loops, query-string mistakes and host-migration errors before they reach production.
As an Amazon Associate I earn from qualifying purchases.
Free tools Windows power users keep installed
One-click scans. No signup required.
The architecture that scales to hundreds of redirects
Nginx’s map directive is designed to turn one variable into another according to a lookup table. Put the map in the global http context, keep its data in a separate file, and use the result in the server that receives the legacy requests.
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 map above uses the original request URI as its key. An entry in /etc/nginx/redirects.map can map an old path to a path on the new host:
#1 Best Overall
/old-product /products/new-product;
/legacy/about https://www.example.com/about;
Map variables are evaluated lazily. Declaring a large map does not itself add request-processing work; Nginx evaluates the variable when the request configuration actually uses it. This makes one included table easier to operate than hundreds of inline directives while keeping request handling predictable.
Map matching has a defined precedence: an exact string wins over a mask, regular expressions are considered after exact and mask matches, and the default value is used when nothing matches. That precedence is the reason exact legacy paths should be recorded as exact entries rather than hidden inside a broad expression.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsDesign the redirect data file
Use one reviewed row per old URL
Treat the included file as data, not as a place to improvise rewrite logic. Each line should contain the old request key, the destination value and a terminating semicolon. Keep the file under the same review and change-control process as the main Nginx configuration.
- Use an exact path key for a one-to-one migration such as
/old-product. - Use a path value such as
/products/new-productwhen the server block will prepend the new host. - Use a complete destination URL when the map value itself is intended to be the entire redirect target.
- Make duplicate old paths fail review or generation rather than allowing one row to silently replace another.
- Record the final canonical destination, not another legacy URL, whenever possible.
A path-only value is convenient when every row goes to the same replacement host. A complete URL is useful when destinations span hosts or when the map is consumed directly by return 301 $redirect_target;. Validate the selected variable and URL form against the Nginx version and the rest of your configuration before production rollout.
Choose a consistent key format
Decide whether the table should distinguish query strings, trailing slashes and encoded characters before generating it. The choice of map variable determines what Nginx compares:
Rank #2
| Key variable | What it represents | Use it when |
|---|---|---|
$request_uri |
The original URI, including the original arguments | The redirect table must distinguish requests by their original query string or preserve the request exactly as received |
$uri |
The normalized URI documented by Nginx | You want matching based on Nginx’s normalized path rather than the original request representation |
Do not mix assumptions. If the business source list contains paths without query strings but the map key includes original arguments, those rows may not match as expected. Likewise, decide explicitly whether both /guide and /guide/ need entries. Case, percent-encoding and slash variants should be tested rather than assumed equivalent.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Use return for fixed destinations
Nginx documents return as the direct mechanism for sending a specific redirect code from server or location context. For a fixed mapping, it states the result plainly and avoids unnecessary pattern processing.
server {
listen 80;
server_name old.example.com;
if ($redirect_target != "") {
return 301 https://www.example.com$redirect_target;
}
}
When the map already contains complete destination URLs, the server-side action can be the simpler form:
return 301 $redirect_target;
Use the second form only when the variable is guaranteed to be a valid complete redirect target and the non-match behavior is handled safely. A blank default must never be emitted as a redirect destination.
Use rewrite only for real patterns
rewrite applies a regular expression and can substitute captured path parts. It is appropriate when a large group of URLs follows one stable transformation, for example:
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuterewrite ^/old-section/(.*)$ /new-section/$1 permanent;
That rule expresses a relationship between many paths. It is not a substitute for a table of unrelated product, article and campaign URLs. A long series of regular expressions is harder to audit, more vulnerable to overlap and more likely to catch a destination accidentally.
Rewrite directives execute sequentially in configuration order. Therefore, two patterns can produce different results merely because one appears earlier in the file. Put the narrowest intended rule first and keep broad patterns last. If exact mappings and patterned transformations coexist, keep the exact map-based entries authoritative and ensure the pattern cannot capture a canonical destination.
| Requirement | Preferred mechanism | Reason |
|---|---|---|
| Hundreds of unrelated old paths | map plus included data file and return 301 |
Centralized, reviewable exact mapping |
| One old host to one new host | Dedicated server block with return 301 |
No conditional path logic is needed |
| A predictable path transformation | rewrite with a carefully bounded regular expression |
One rule can represent the genuine pattern |
| Mixed fixed and patterned redirects | Exact map entries plus separately ordered pattern rules | Explicit precedence reduces accidental matches |
Keep host migrations in a dedicated server block
When an entire hostname is moving, define a separate server for the old hostname. The Nginx conversion guidance describes this as the right approach rather than embedding host migration in conditional rewrite logic.
server {
listen 80;
server_name example.org;
return 301 http://www.example.org$request_uri;
}
This block has one responsibility: every request arriving for the old host receives the new host and the original request URI. Keep path-specific exceptions in the appropriate old-host server, and make sure the canonical host does not also match the redirecting server block. A rule that catches its own destination can create a loop.
Handle precedence, query strings and URL edge cases deliberately
Exact entries versus broad expressions
Place exact paths in the map and reserve broad regular expressions for paths that truly share a transformation. Exact strings have priority over masks; regular expressions are considered in their listed order. If two regexes can match the same request, the first applicable one wins, so ordering is part of the behavior, not formatting.
Rank #4
Trailing slashes and case
Decide whether the source system treated /old-page and /old-page/ as separate URLs. Add explicit rows or a deliberate normalization rule for both if they can arrive in production. Do the same for case variants when the old application exposed them. Never rely on a browser’s correction to hide an incomplete migration table.
Arguments and encoded paths
$request_uri includes the original arguments, while $uri is normalized. A map keyed by the former can distinguish requests that differ only by a query string; a map keyed by the latter cannot. Percent-encoded characters can also make the original and normalized representations differ. Include encoded-path and query-string cases in testing, and choose the key that matches the source inventory’s format.
Prevent redirect chains and loops
A redirect chain occurs when an old URL points to another legacy URL, which then redirects again. A loop occurs when rules send a request back to a URL that matches the same redirect logic, including a canonical host accidentally caught by an old-host rule. Both waste crawler and client requests and can prevent users from reaching the destination.
- Resolve each old path directly to its final canonical URL.
- Search the mapping source for destinations that are also old keys.
- Keep old-host server blocks separate from canonical-host blocks.
- Do not write a broad regex that can match its own replacement path.
- Check both the status code and every
Locationvalue during testing.
Rewrite processing can repeat location selection, but Nginx limits rewrite cycles to 10. A configuration that keeps rewriting rather than settling can therefore end in a 500 error. A 500 in this situation is a configuration-cycle symptom, not evidence that the destination is unavailable.
Build a safe rollout workflow
- Normalize the source inventory. Decide the key form, slash policy, query-string policy and final destination format before generating the map.
- Generate the included file. Produce one exact row per old URL and make duplicate old paths fail the build or review process.
- Review destinations. Check that each target is final, uses the intended host and has the expected path and encoding.
- Install the include. Place the file at the path named by the
includedirective and verify that the Nginx worker can read it. - Validate syntax. Run
nginx -t. Do not reload if Nginx reports an error in the main file or an included file. - Reload normally. Use your operating system’s standard Nginx service-management procedure so the validated configuration replaces the active one without stopping the service unnecessarily.
- Run redirect tests. Check representative exact hits, misses, query strings, slash variants, encoded paths and old-host requests.
- Inspect post-deployment logs. Look for unexpected 3xx sequences, 404 responses and requests that indicate a loop or an incomplete source list.
A syntax test proves that Nginx can parse the configuration; it does not prove that every destination is correct. Functional checks against the mapping file remain necessary.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Test status and Location for every mapping
Use a header-only HTTP client check for each old URL, or for an automated sample that covers every rule class. For example:
curl -I http://old.example.com/old-product
Confirm that the response is 301 and that the Location header is exactly the intended destination. A correct status with a wrong host, missing path, unexpected slash or malformed query string is still a failed migration.
Minimum test matrix
| Case | What to verify |
|---|---|
| Exact mapped path | Returns 301 and the expected final destination |
| Unmapped path | Does not receive an accidental redirect from a broad rule |
| Query string | Arguments are preserved, discarded or transformed exactly as intended |
| Trailing-slash variant | The chosen slash policy is applied consistently |
| Percent-encoded path | The key representation matches the map variable used |
| Old hostname | The dedicated host redirect reaches the canonical host once |
| Canonical hostname | It is not caught by the old-host redirect block |
| Destination URL | It does not redirect again to another legacy URL |
For a table with hundreds of entries, automate the check from the same reviewed source list used to generate the map. The important result for each row is the pair of values: HTTP status and Location. Keep failed rows with the deployment review so a correction can be made without losing the original case.
Observe the migration after release
Sample access logs after deployment and group requests by status and destination. Unexpected 3xx chains indicate that a target is still legacy or that another server is adding a redirect. 404s on known old URLs indicate a missing mapping, a key-format mismatch or a request reaching the wrong server block. A sudden increase in 500 responses warrants checking rewrite-cycle behavior and the active configuration.
Keep the redirect file separate from unrelated virtual-host settings. That makes additions, removals and incident rollback auditable: a change to one URL should not require editing a large block of unrelated directives. When a page is permanently retired, remove its row only after confirming that the old URL no longer needs to transfer visitors or search signals.
Quick Recap
Troubleshoot common failures
nginx -t fails after adding the map
- Check the included file path and permissions.
- Confirm every map row ends with a semicolon.
- Look for an unescaped character or malformed URL in the generated data.
- Verify that the
mapis declared inhttpcontext, not inside aserverorlocationblock.
The request returns 200 or 404 instead of 301
- Confirm the request reached the server whose
server_namematches the old host. - Check whether the map key uses
$request_uriwhile the data file contains normalized paths, or vice versa. - Compare the exact slash, case and percent-encoding of the request with the table row.
- Ensure the non-empty test is using the same map variable populated by the include.
The status is 301 but the destination is wrong
- Inspect exact-versus-regex precedence and the order of competing patterns.
- Check whether a complete URL was inserted into a configuration that also prepends the new host.
- Look for a destination that points to another old key, creating a chain.
The browser reports too many redirects
- Request the old URL with headers and follow each
Locationvalue manually. - Check whether the canonical host is handled by the old-host server block.
- Test the final URL directly to ensure it does not match a broad rewrite.
- Inspect rewrite cycles; Nginx stops after 10 rewrite iterations and may return 500.
Operational checklist
- One reviewed source list is the input for both map generation and testing.
- Exact old paths are represented as exact map keys.
- Pattern rules are limited to genuine transformations and ordered deliberately.
- Host migrations use dedicated server blocks.
- Query strings, slashes, case and encoding have an explicit policy.
- Destinations point directly to final canonical URLs.
nginx -tpasses before every reload.- Tests inspect both 301 status and the exact
Locationheader. - Logs are checked for chains, loops, unexpected 404s and 500s after release.
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.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →

