Halloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run ScanHalloween DealsAmazon USOctober picks are moving - compare before checkoutAmazon US: current deals, useful picks and tech finds.See Picks×
FREEDOM251

Freedom251 › Blog › 301 redirects

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

By Freedom251 Team · · 9 min read

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

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.

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.

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

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:

/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.

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

Design 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-product when 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:

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.

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

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:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
rewrite ^/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.

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

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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • 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 Location value 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

  1. Normalize the source inventory. Decide the key form, slash policy, query-string policy and final destination format before generating the map.
  2. Generate the included file. Produce one exact row per old URL and make duplicate old paths fail the build or review process.
  3. Review destinations. Check that each target is final, uses the intended host and has the expected path and encoding.
  4. Install the include. Place the file at the path named by the include directive and verify that the Nginx worker can read it.
  5. Validate syntax. Run nginx -t. Do not reload if Nginx reports an error in the main file or an included file.
  6. 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.
  7. Run redirect tests. Check representative exact hits, misses, query strings, slash variants, encoded paths and old-host requests.
  8. 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.Support on Ko-Fi

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.

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

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.

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 map is declared in http context, not inside a server or location block.

The request returns 200 or 404 instead of 301

  • Confirm the request reached the server whose server_name matches the old host.
  • Check whether the map key uses $request_uri while 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 Location value 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 -t passes before every reload.
  • Tests inspect both 301 status and the exact Location header.
  • 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.

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

301 redirectsNGINXSEOserver configurationURL migrationweb servers

Leave a Reply

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

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.

Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

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.