# Common Mistakes — Nginx

Source: https://www.skillbyai.com/en/nginx/p-pitfalls

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

```nginx
# 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.

**Quiz:** What is the generally recommended alternative to complex `if` logic inside locations?

- [ ] Nested if statements
- [x] 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.
