Requests and static files

Return redirects and errors

Use explicit responses and redirects, preserve methods when required, and avoid redirect loops.

8 minute lesson

~~~

Nginx can answer a request without reading a file or contacting an upstream. The return directive produces the response directly, and it’s the right tool for redirects, health checks, and hard rejections.

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

  location = /health {
    return 200 "ok\n";
  }

  location = /old-pricing {
    return 301 /pricing;
  }

  location = /promo-2025 {
    return 302 /pricing;
  }
}

The /health location answers with a body and no filesystem access at all. Monitoring systems can hit it thousands of times a day without touching your application.

For redirects, the status code is a real decision. 301 means permanent: browsers and search engines cache it, often aggressively, and there is no practical way to un-teach a browser that has seen it. 302 means temporary and stays revisitable. My advice is to ship a 302 first, watch it behave for a few days, then upgrade to 301 only when the mapping is stable.

There is a second axis: the request method. With 301 and 302, most clients resend the follow-up request as a GET, even if the original was a POST. Use 307 (temporary) or 308 (permanent) when the request method must be preserved — an API endpoint that moved, for example, where turning a POST into a GET would silently break clients.

Verify status and destination with curl -I:

curl -I http://www.example.com/old-pricing
# HTTP/1.1 301 Moved Permanently
# Location: /pricing

curl -s http://www.example.com/health
# ok

Then check the destination doesn’t bounce back. Redirect loops happen when the target location itself redirects — often through a rewrite rule or an HTTPS redirect added later in another block. Follow the chain end to end:

curl -sIL -o /dev/null -w "%{num_redirects} redirects -> %{url_effective}\n" http://www.example.com/old-pricing
# 1 redirects -> http://www.example.com/pricing

More than one hop deserves a look. Twenty hops means a loop: curl gives up with Maximum (50) redirects followed, and browsers show “too many redirects”.

Add a temporary old-path redirect and a plain /health response to your test server. Inspect status and Location headers with curl -I before choosing permanent caching.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →