Deep Analysis and Comparison of $host vs $http_host Variables in Nginx

Nov 26, 2025 · Programming · 7 views · 7.8

Keywords: Nginx Configuration | HTTP Variables | Server Name

Abstract: This article provides an in-depth exploration of the differences and relationships between the $host and $http_host variables in Nginx configuration. Through analysis of official documentation and practical examples, it details the intelligent fallback mechanism, port handling rules, and lowercase conversion features of $host, as well as the raw characteristics of $http_host as a direct mapping of HTTP headers. The article includes comprehensive code examples and practical guidance for server name configuration and rewrite rules, helping developers accurately understand and correctly use these key variables.

Overview of Nginx Variable System

Nginx, as a high-performance web server and reverse proxy, offers a powerful variable system that provides significant flexibility in configuration. During HTTP request processing, Nginx supplies a rich set of built-in variables to access various request attributes and header information. Among these, $host and $http_host are two frequently confused yet critically important variables.

The Nature of $http_host Variable

The $http_host variable belongs to the generic header variable series of Nginx's core module, following the naming convention of $http_HEADER. This variable directly maps to the Host field in the HTTP request header, preserving the complete format from the original request.

From a technical implementation perspective, the value of $http_host is an exact copy of the Host header content sent by the client in the HTTP request. This means:

# Example: When client request header is "Host: example.com:8080"
# $http_host value is "example.com:8080"

# Configuration example: Logging original Host header
location /log-headers {
    access_log /var/log/nginx/access.log '$http_host';
}

This direct mapping characteristic makes $http_host invaluable in scenarios requiring precise matching of original request headers.

Intelligent Features of $host Variable

In contrast, the $host variable exhibits more intelligent and robust behavioral characteristics. According to Nginx official documentation, the value determination of this variable follows specific priority rules:

# Intelligent fallback mechanism example
server {
    listen 80;
    server_name backup.example.com;
    
    location / {
        # When Host header is missing or empty, $host uses server_name value
        return 200 "Host: $host\n";
    }
}

The core characteristics of the $host variable can be summarized into three key aspects:

Automatic Port Stripping

When the HTTP request's Host header includes a port number, $host automatically removes the port portion, retaining only the hostname:

# Input: Host: www.example.com:8080
# $http_host = "www.example.com:8080"
# $host = "www.example.com"

# Practical configuration application
location /api {
    # In rewrite rules, typically only the hostname is needed, not the port
    rewrite ^/api/(.*)$ https://$host/v2/$1 permanent;
}

Server Name Fallback Mechanism

In special cases where the Host header is missing or has an empty value, $host falls back to the value configured in the server_name directive of the current server block:

server {
    listen 80 default_server;
    server_name fallback.example.com;
    
    # When client doesn't send Host header
    # $host = "fallback.example.com"
    
    location / {
        proxy_pass http://backend/$host$request_uri;
    }
}

Lowercase Normalization

Since Nginx version 0.8.17, the value of $host is always converted to lowercase, helping to avoid matching issues caused by case inconsistencies:

# Input: Host: WWW.Example.COM
# $http_host = "WWW.Example.COM"  # Preserves original case
# $host = "www.example.com"       # Uniformly converted to lowercase

# Application in virtual host matching
server {
    server_name www.example.com;
    # Even if client sends uppercase Host header, $host still matches correctly
}

Practical Scenario Analysis and Code Examples

Correct Choice in Rewrite Rules

In URL rewriting scenarios, selecting the appropriate variable is crucial. The reference article case demonstrates typical application during forum system migration:

location = /vb/showthread.php {
    # Handling old forum post link redirections
    if ($arg_p) {
        # Using $host ensures redirection to correct hostname
        return 301 $scheme://$host/forum/index.php?posts/$arg_p/;
    }
}

In this example, choosing $host over $http_host offers distinct advantages:

Variable Application in Proxy Configuration

In reverse proxy scenarios, the choice between variables affects the information received by backend servers:

location /proxy/ {
    # Option A: Pass original Host header
    proxy_set_header Host $http_host;
    
    # Option B: Pass processed hostname
    proxy_set_header Host $host;
    
    proxy_pass http://backend-server;
}

Option A preserves the client's original request information, suitable for scenarios requiring exact replication of client requests. Option B provides more standardized and robust hostname passing, particularly suitable for multi-environment deployments.

Comprehensive Comparison and Best Practices

<table border="1"> <thead> <tr> <th>Characteristic</th> <th>$http_host</th> <th>$host</th> </tr> </thead> <tbody> <tr> <td>Data Source</td> <td>Directly from HTTP Host header</td> <td>Intelligent combination: Host header → server_name fallback</td> </tr> <tr> <td>Port Handling</td> <td>Includes port number (if present)</td> <td>Automatically removes port number</td> </tr> <tr> <td>Case Sensitivity</td> <td>Preserves original case</td> <td>Uniformly converted to lowercase</td> </tr> <tr> <td>Empty Value Handling</td> <td>May be empty or undefined</td> <td>Always has valid value (fallback mechanism)</td> </tr> <tr> <td>Suitable Scenarios</td> <td>Scenarios requiring original request information</td> <td>General configuration, redirections, virtual host matching</td> </tr> </tbody>

Configuration Recommendations

Based on in-depth analysis, we propose the following configuration suggestions:

# Recommended scenarios for using $host
server {
    server_name example.com www.example.com;
    
    # 1. General redirections
    if ($host = 'www.example.com') {
        return 301 https://example.com$request_uri;
    }
    
    # 2. Virtual host routing
    location /app1 {
        # Using $host ensures correct hostname identification
        proxy_pass http://app1-backend/$host$request_uri;
    }
    
    # 3. Log recording
    access_log /var/log/nginx/access.log '$host - $remote_addr';
}

# Special scenarios requiring original information
location /debug {
    # Record complete original Host header for debugging
    add_header X-Original-Host $http_host;
    return 200 "Debug info recorded";
}

Conclusion

Through systematic analysis, we can clearly recognize the different roles and values of $host and $http_host in Nginx configuration. $http_host, as a direct mapping of the original HTTP header, is indispensable in scenarios requiring precise replication of client request information. Meanwhile, $host, with its intelligent fallback mechanism, automatic port stripping, and lowercase normalization features, provides better robustness and convenience in most general configuration scenarios.

In practical Nginx configuration work, understanding the fundamental differences and applicable scenarios of these two variables enables developers to make more informed choices and build more stable and reliable web service architectures. It is recommended to prioritize using $host in regular configurations, reserving $http_host only for special scenarios that genuinely require original request information.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.