Hardware FixRecommendedDevice not working? Your driver may be the problemCheck updates for common hardware issues.Fix DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run Scan×
Skip to content
VGSources
Blog

How to Set Up 301 Redirects for Hundreds of URLs in Nginx

A practical Nginx guide to maintaining hundreds of 301 redirects with an included map, exact-match precedence, safe host migrations, and curl-based testing.
WorldNginx Length10 min Posted Quest giverVGSources Team
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For hundreds of fixed URL moves, the maintainable Nginx design is an http-context map whose entries live in a separate included file. Each old path maps directly to its final destination, and a return 301 sends the redirect. Use rewrite only when a genuine regular-expression pattern can replace many URLs. Validate the configuration with nginx -t, reload through your normal service process, then test both the status code and every Location header.

This approach keeps a large redirect inventory reviewable, gives exact paths predictable precedence, and avoids scattering hundreds of directives through server and location blocks.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use a map and an included file for a large redirect list

An Nginx map is designed to translate one variable into another. It supports exact string keys, masks, regular expressions, a default value, and an include directive for loading entries from another file. Put the map in the http context, then use the resulting variable in the server that receives the legacy requests.

Map variables are evaluated lazily. Declaring a large map does not itself add request-processing work; evaluation occurs when a request uses the mapped variable. That makes an included table practical even when it contains hundreds or thousands of entries.

Base configuration

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 reads the original request URI and stores the selected destination in $redirect_target. The empty default means that an unmapped request is not redirected by this block. The conditional return runs only when a destination was found.

Format the included data file

Each map entry is a key followed by a value and a semicolon. Keep one mapping per line so reviews, diffs, and automated generation remain straightforward.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
/old-product /products/new-product;
/legacy/about https://www.example.com/about;

The first value is a path, so the server block adds the destination host. The second value is already an absolute URL. Choose one convention for your project and document it; mixing conventions is valid, but it makes generation and review easier to get wrong.

Store the table outside the main configuration

Generate /etc/nginx/redirects.map from a reviewed source list rather than hand-editing hundreds of lines in the main file. Make duplicate old paths fail your build or review process. A duplicate key can otherwise hide a mistake, especially when a later edit appears to change a redirect but does not win according to map matching rules.

Choose the correct key and destination format

$request_uri versus $uri

$request_uri contains the original URI, including the original arguments (query string). $uri is Nginx’s normalized URI variable. Select the one that matches the inventory you are importing:

  • Use $request_uri when query strings or the original encoded form are part of the mapping decision.
  • Use $uri when the table is based on normalized paths and query strings should not distinguish entries.

Do not assume that a path-only key covers every query-string case when the map is keyed by $request_uri. Verify the exact requests your old links generate.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Relative paths and absolute URLs

A path value such as /products/new-product is useful when every destination stays on the new host. The server block can prepend https://www.example.com. An absolute value such as https://www.example.com/about is clearer when destinations vary by host or when you want the data file to be self-contained.

If the map value is always a complete destination URL, the server can use a direct return:

map $request_uri $redirect_target {
    default "";
    include /etc/nginx/redirects.map;
}

server {
    listen 80;
    server_name old.example.com;

    if ($redirect_target != "") {
        return 301 $redirect_target;
    }
}

Check the URL form and variable usage against the Nginx version running in production before rollout, especially if you change from path values to complete URLs.

Understand matching precedence before adding rules

Nginx evaluates map keys in a defined order. Exact strings are selected before masks, regular expressions are considered in their listed order, and the default value handles everything else. This order determines which destination wins when a specific path also fits a broad pattern.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Entry type Typical use What to watch
Exact string One old URL to one destination Use for the bulk of a reviewed migration table.
Mask or wildcard A controlled family of names Confirm it does not unexpectedly capture a more specific path.
Regular expression Patterned transformations Regex entries are considered in the order written; broad expressions can steal matches.
default Fallback for misses An empty default is useful when unmapped requests should continue normally.

Put exact paths in the data set and keep broad expressions below them. If a migration has an exception, represent that exception as an exact entry and test it explicitly.

Use return 301 for fixed mappings

Nginx documents return as the direct mechanism for sending a specific redirect status from server or location context. It is the clearest choice when an old URL has a known final destination.

server {
    listen 80;
    server_name old.example.com;

    location = /old-product {
        return 301 https://www.example.com/products/new-product;
    }
}

For hundreds of entries, the map keeps those fixed destinations in data rather than repeating inline directives. Use an inline return for a small exception or a special host rule, not as the default way to maintain a large inventory.

Use rewrite only for real patterns

rewrite applies a regular expression and can substitute captured path parts. It is appropriate when many old URLs share a reliable structure, such as moving an entire section while preserving a slug.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
server {
    listen 80;
    server_name old.example.com;

    rewrite ^/old-section/(.*)$ https://www.example.com/new-section/$1 permanent;
}

The permanent flag produces a 301 response. Rewrite directives execute sequentially in the order they appear, so ordering is part of the behavior. Place a narrow rule before a broader one, and do not add a regex merely to avoid creating a data file when the redirects are actually one-off mappings.

Why a broad rewrite can be dangerous

A pattern that also matches its own destination can redirect repeatedly. A rule that catches the already-canonical host can create a host loop. Rewrite processing can also repeat location selection; Nginx limits rewrite cycles to 10, and a cycle can end in a 500 error. Treat every regex as code: define its intended input set, its final output, and a test for a URL that must not match.

Keep host migrations in a dedicated server block

When an entire hostname is moving, define a separate server for the old host and return the new host with the original request URI:

server {
    listen 80;
    server_name example.org;
    return 301 http://www.example.org$request_uri;
}

A dedicated old-host server is preferable to conditional rewrite logic. It makes the host boundary explicit and prevents a redirect intended for the legacy hostname from affecting requests already sent to the canonical host.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

If the destination should be HTTPS, use the final HTTPS URL in the return. If the migration also changes paths, use a map in the old-host server instead of combining an unconditional host redirect with a second path redirect; that combination commonly creates chains.

Prevent chains, loops, and accidental misses

Point directly to the final URL

A chain such as /a to /b to /c adds requests and makes failures harder to diagnose. Build the table so every legacy URL points directly to /c, the final canonical destination, whenever the final destination is known.

Check slash and case variants

Decide whether /guide and /guide/ are separate inputs in your inventory. Test both if users or old links may send both. Do the same for case differences; do not assume a case variant will match an exact map key.

Check encoding and arguments

Percent-encoded paths can look different from their decoded form, and $request_uri preserves the original request representation. Include encoded examples in testing. Query strings may need to be preserved, discarded, or mapped to a different destination; encode that decision in the table and verify it with an actual request.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Do not redirect the canonical request back to itself

Confirm that the old-host server is not selected for the new host and that a destination URL does not match the conditions that trigger the old rule. A self-targeting rule can loop even when the path mapping itself looks correct.

Roll out the map safely

  1. Prepare a source list. Keep the old path, intended final URL, and any notes in a reviewable format. Generate the Nginx include file from that source.
  2. Reject duplicate inputs. Make duplicate old paths fail generation or require an explicit review decision.
  3. Review high-risk entries. Inspect host changes, encoded paths, trailing-slash variants, query-string behavior, and any regexes separately from ordinary exact mappings.
  4. Install the include file. Ensure the Nginx worker can read the file and that the path in include exactly matches the installed location.
  5. Validate syntax. Run sudo nginx -t. Do not reload if the test reports an error; the output identifies the configuration file and line that needs correction.
  6. Reload normally. Use your operating system or container’s normal Nginx service-management process. A reload applies the new configuration without treating a syntax failure as a successful deployment.
  7. Test before broad traffic arrives. Check representative exact hits, misses, host requests, query strings, slash variants, and encoded paths.
  8. Inspect post-deployment logs. Look for unexpected 3xx chains, 404 responses at destinations, and repeated requests that indicate a loop.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Test status and Location for every URL

A redirect is correct only when both its status and destination are correct. Nginx’s redirect guidance demonstrates checking headers with curl; use the same approach for your migration.

Inspect one response

curl -sS -D - -o /dev/null https://old.example.com/old-product

For a mapped entry, verify a 301 status and a Location header pointing to the intended final URL. The body is irrelevant to this check, so -o /dev/null keeps the output focused on headers.

Follow the chain when diagnosing

curl -sS -I -L https://old.example.com/old-product

Use a follow-redirect request to reveal whether an old URL reaches the final destination through extra hops. A migration table should normally produce one redirect from the old URL to the canonical URL, not a sequence of legacy redirects.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Run a batch check from the reviewed source list

Keep testing data separate from the Nginx syntax file. For a two-column list containing an old path and expected absolute URL, a shell loop can issue one header request per row:

while IFS=' ' read -r old_path expected; do
    printf 'n%sn' "$old_path"
    curl -sS -D - -o /dev/null "https://old.example.com${old_path}"
done < redirect-test-list.txt

Compare each response’s status and Location with the expected value. Include unmapped paths in the test list to confirm they do not receive an unintended redirect.

Troubleshoot common failures

nginx -t reports an include or syntax error

  • Confirm the included file exists at the exact path in the include directive.
  • Check that every map entry ends with a semicolon and that values containing spaces are quoted appropriately.
  • Look at the reported line number in both the main configuration and the generated data file.
  • Do not reload until the test passes.

The request returns 200 instead of 301

  • Confirm the request reached the server whose server_name matches the old host.
  • Verify that the map key matches the variable you selected: $request_uri and $uri do not represent the same input in every case.
  • Check the exact path, trailing slash, case, encoding, and query string.
  • Ensure the map’s default is not being mistaken for a destination; an empty default should leave an unmapped request untouched.

The wrong destination wins

Look for a broad mask or regular expression that also matches the request. Exact keys have priority over masks, and regular expressions are considered in their listed order. Move or narrow the expression and add a test for the exception.

The response loops or ends in 500

Use curl -I -L to see each hop. Check whether the destination matches the source rule, whether the canonical host is being caught by the old-host server, and whether multiple rewrite directives send the request back through the same pattern. Nginx stops after 10 rewrite cycles, so a cycle can surface as a 500 response.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The redirect has an unexpected query string

Recheck whether the map is keyed by $request_uri, which includes original arguments, or by $uri, which is normalized. Test the exact query-string variants that matter to your application and make the destination value explicit for each required behavior.

Maintain the redirect inventory after launch

Treat the map as a controlled data set, not a permanent dumping ground. Keep the source list under review, regenerate the include file consistently, and preserve a record of why exceptional entries exist. When a destination changes, update the old URL directly to the new final URL instead of adding another intermediate redirect.

After deployment, sample access logs for unexpected 3xx responses, destination 404s, and repeated requests. Remove obsolete mappings only when you have verified that the old URLs no longer need coverage; deleting an entry changes an intentional 301 into whatever behavior the server uses for an unmapped request.

Decision guide: map, return, or rewrite

Situation Preferred mechanism Reason
Hundreds of unrelated old paths map plus an included file and return 301 Centralizes exact mappings and keeps the main configuration readable.
A handful of fixed exceptions Inline return 301 Direct and easy to audit.
Many URLs share one proven path pattern rewrite ... permanent Captures and substitutes the changing path portion.
Entire hostname migration Dedicated old-host server with return 301 Keeps host handling separate from path logic.

For the title’s specific case—hundreds of known old URLs—the map-and-include design with direct 301 destinations is the safest default. Reserve regex rewrites for transformations you can describe precisely and test without ambiguity.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More quests from Patch Notes

  1. How to Set Up a RedM (RDR2) Server in 2026: License Key, txAdmin and server.cfg, Step by StepBlog11min
  2. Best RedM (RDR2) Server Hosting in 2026: Comparing Four Hosts on Slots, Memory and PriceBlog10min
  3. How to Host a Mindustry Server in 2026: server-release.jar, Port 6567 and the Commands That MatterBlog7min
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.