An nginx instance has several `server` blocks that all declare `listen 80;` with different `server_name` values. How does nginx decide which block handles an incoming request, and what happens when the request's Host header matches no `server_name` at all?
answer
- listen first, then the name
- Host header picks the block
- unmatched names still get served
- default_server, or the first block
- underscore is a convention, not magic
basics
~20 sNginx first narrows candidates by the listen address and port, then matches the request's Host header against server_name. If no name matches, the request goes to that socket's default server: the block whose listen carries default_server, or otherwise the first such block in the configuration.
solid answer
~40 sSelection happens in two stages. Nginx first picks the `server` blocks whose `listen` matches the socket the connection arrived on, preferring the most specific address (an explicit IP beats a wildcard). Among those it compares the request's `Host` header against `server_name`, trying an exact name first, then wildcards such as `*.example.com`, then regular expressions in file order. If nothing matches — a bare IP request, an unknown vhost, a scanner — nginx does **not** return an error. It uses the **default server** for that listen socket: the block whose `listen` line carries `default_server`, or, if none does, simply the first `server` block declared for that address and port. That is why an unconfigured domain pointed at your box lands on whatever site happens to be first in the config.
code
nginx · 17 linesserver {
listen 80 default_server;
server_name _;
return 444;
}
server {
listen 80;
server_name shop.example.com;
root /srv/shop;
}
server {
listen 80;
server_name *.api.example.com;
root /srv/api;
}go deeper
Be able to say that listen plus server_name choose the server block, and that a request whose Host matches nothing still gets served — by the default server or the first block declared.
Explain the two stages and the name-matching priority: exact, then leading wildcard, then trailing wildcard, then regex in file order. Say plainly that default_server, not server_name _, sets the fallback.
Show why an accidental default is an operational problem: unknown domains pointed at your IP serve a real customer's site and pollute its logs. Describe the deliberate catch-all block you would add.
Own the estate-wide rule: every listen socket gets an explicit default_server that refuses unknown names, so vhost sprawl cannot silently expose one tenant's site under another's name, and say how that gets enforced.
## Stage one: the listen socket Before any name is considered, nginx narrows the candidate set by `listen`. A block with `listen 192.0.2.10:80;` is more specific than one with `listen 80;` (which means `*:80`), and the more specific address wins the socket. Only blocks that share the winning address:port compete in stage two. This is the reason a `server_name` change sometimes has no effect at all — the block was never a candidate for that socket in the first place. ## Stage two: matching the Host header Among the candidates, nginx compares the request's `Host` header against each `server_name`, in this priority order: 1. **Exact name** — `server_name www.example.com;` 2. **Longest wildcard starting with an asterisk** — `server_name *.example.com;` 3. **Longest wildcard ending with an asterisk** — `server_name www.example.*;` 4. **First matching regular expression**, in the order the blocks appear in the configuration — `server_name ~^www\d+\.example\.com$;` The first three tiers are decided by specificity, not file order; only the regex tier depends on where the block sits in the file. ## Stage three: nobody matched This is the part interviewers actually probe. Nginx never fails a request for having an unknown `Host`. It falls back to the **default server** of the listen socket: - the block whose `listen` directive carries the `default_server` parameter, or - if no block claims it, the **first** `server` block declared for that address:port. ```nginx server { listen 80 default_server; server_name _; return 444; # close without a response } server { listen 80; server_name shop.example.com; root /srv/shop; } ``` Here every request with an unrecognised `Host` — a raw IP hit, a stale DNS record, a scanner probing for vhosts — is answered by the first block. `return 444` is nginx's non-standard code meaning "close the connection with no response", a common choice for that catch-all. ## Two conventions people misread **`server_name _;` is not magic.** The underscore is simply a name that can never appear as a real `Host`, so the block matches nothing by name. It is a readability convention for a catch-all; what actually makes the block the catch-all is `default_server` on the `listen` line — or being declared first. Writing `server_name _;` without `default_server` on a socket where another block comes first achieves nothing. **`server_name "";`** is the one that matches requests carrying an empty or absent `Host` header. ## Why the default server matters operationally Without an explicit default, the first block in your config silently becomes the answer for every unknown hostname. If that block is a customer's production site, then anyone who points a domain at your IP serves their traffic from your customer's site, and your logs mix the two. The standard hardening is to declare a deliberate `default_server` that returns `444` or a `403`, so that only names you configured on purpose are served. A second consequence is diagnostic: when a new vhost "shows the wrong site", the cause is almost always that its `server_name` is not being matched (typo, missing DNS, wrong listen address) and the request is falling through to the default. Logging `$host` and `$server_name` side by side in the access log settles it immediately — `$host` is the name the client asked for, `$server_name` is the block that answered.
- Does `server_name _;` make a block the default server?No. The underscore is just a name that cannot occur as a real Host, so the block matches nothing by name — it is a readability convention. What makes a block the default is the `default_server` parameter on its `listen` line, or, failing that, simply being the first block declared for that address and port.
- In what order are `server_name` values matched when several could apply?Exact names first; then the longest wildcard beginning with an asterisk, such as `*.example.com`; then the longest wildcard ending with one, such as `www.example.*`; and finally the first matching regular expression in configuration order. Only the regex tier depends on file order — the rest is decided by specificity.
- A new vhost was added but requests keep landing on an older site. How do you confirm what happened?Log `$host` and `$server_name` together: `$host` is the name the client sent, `$server_name` is the block that answered. If they disagree, the request fell through to the default server, which points at a `server_name` typo, a `listen` address that made the block ineligible, or DNS still resolving elsewhere.
saying these in an interview costs you the question
- Says nginx returns an error for an unknown Host
- Claims server_name _ is what makes a block default
- Thinks server blocks are tried top to bottom by name
- Ignores listen and matches on server_name alone
- Assumes a wildcard name beats an exact one