Lesson 23 / 25
Common Mistakes
Recognise and fix the most frequent NGINX configuration errors.
Mistakes everyone makes once
if in location blocks: NGINX's if is part of the rewrite module and behaves surprisingly with most directives (the official wiki famously calls it "evil"); use it only for return and rewrite, and prefer map and try_files. proxy_pass trailing slash confusion changes the URI sent upstream. Missing forwarded headers make apps generate HTTP links or wrong client IPs. add_header in a location silently dropping server-level headers. root versus alias mix-ups produce 404s. Regex locations unexpectedly overriding prefixes. Using $host vs $http_host: $host is normalised and safer. Long default timeouts (60 s connect) hiding upstream problems. Forgetting nginx -t before reload. Exposing .git, .env or backup files from the web root. Rate limiting the proxy's IP instead of the client's. Default server serving a real site to arbitrary Host headers. Most of these are caught by reading nginx -T output carefully and testing with curl before and after changes.
Replacing if with map
map is evaluated lazily and avoids if's pitfalls.
# fragile:
# location / {
# if ($http_user_agent ~* "bot") { set $is_bot 1; }
# ...
# }
# better: compute the variable once with map (http context)
map $http_user_agent $is_bot {
default 0;
~*(bot|crawler) 1;
}
map $is_bot $bot_limit_key {
0 ""; # empty key = not limited
1 $binary_remote_addr;
}
limit_req_zone $bot_limit_key zone=bots:10m rate=1r/s;
server {
location / {
limit_req zone=bots burst=5;
proxy_pass http://app_backend;
}
}Pilot checklists
Pilots run a checklist before every flight, not because they forget how to fly but because small omissions are deadly. nginx -t, nginx -T and a curl check are your pre-flight checklist.
Quick check: What is the generally recommended alternative to complex `if` logic inside locations?
- Nested if statements
- map blocks and try_files
- Lua scripts in every location
- Disabling the rewrite module
Answer
map blocks and try_files — map computes variables cleanly and try_files handles file fallbacks without if.