Compare $host, $http_host, and $server_name in Nginx

Choose the parsed request hostname, received Host header, or selected server name deliberately for proxying, logging, and redirects.

Best practices
Illustration of network request routing and access controls

$host is Nginx's parsed hostname, $http_host represents the received Host header value, and $server_name identifies the server configuration handling the request. They differ when a port is present, a header is missing, or the request does not use the server's first configured name.

Variable Source Example
$host Hostname from the request line, then Host header, then the matching server name. example.com
$http_host Host header value, if present. example.com:8080
$server_name Configured name of the selected server, normally its first name. example.com

For an HTTP request with Host: example.com:8080, $http_host can retain the port while $host normally omits it. If the request line contains an absolute URI with a hostname, that hostname takes precedence in $host. This does not mean every malformed or missing-Host request is accepted; HTTP validation rules still apply.

Log the three values separately

Define the format in http, then use its name in the server:

http {
    log_format host_debug '$remote_addr host="$host" '
                          'http_host="$http_host" server="$server_name" '
                          'status=$status request="$request"';
    server {
        listen 8080;
        server_name example.com www.example.com;
        access_log /var/log/nginx/host-debug.log host_debug;
    }
}

Merge these directives into the appropriate contexts of an existing configuration; this fragment is not a complete replacement main file. The second argument to access_log is a format name, not a literal formatting string.

Test the configuration, reload it, and send a request with an explicit Host header:

curl -i -H 'Host: www.example.com:8080' http://127.0.0.1:8080/

For the shown server, compare the requested www name with the configured primary name. Whether the request returns content depends on the site's actual handler.

Choose the variable for the operation

proxy_set_header Host $host; passes a parsed hostname with a fallback. If the backend needs the original port, decide how to validate and preserve that value rather than swapping variables without considering routing.

For a fixed canonical redirect, use a fixed destination:

return 301 https://example.com$request_uri;

Both request-line and header host information originate from the client. For a multi-domain redirect, restrict the accepted hosts before reflecting a requested hostname into a destination. $host normalization does not make an arbitrary host trusted.

Log $host and $http_host when diagnosing client requests, and keep $server_name separate when checking virtual-host selection. The Guance Nginx integration can collect a custom format once its parsing is configured; verify a known request before grouping the fields as if they were interchangeable.

References: Nginx variables, access-log configuration.

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting