How to Fix Missing HTTP_HOST with Nginx, HTTP/3, and PHP-FPM
The Problem: HTTP_HOST Disappears with HTTP/3
If you’ve recently upgraded to HTTP/3 on your Nginx server hosting WordPress or other PHP applications, you might have encountered some frustrating issues:
- WordPress redirecting to
https:///
(missing domain) - Broken links throughout your site
- Failed WordPress upgrades
- Multi-domain setups breaking mysteriously
- Cache plugins creating inconsistent paths
These problems all stem from a single source: the HTTP_HOST
variable goes missing when serving requests over HTTP/3, breaking critical functionality in PHP applications.
Understanding the Root Cause
HTTP/3 fundamentally changes how headers are handled. While traditional HTTP protocols use the Host
header, HTTP/3 uses the :authority
pseudo-header instead. By default, Nginx doesn’t properly translate this value when passing it to PHP-FPM, resulting in $_SERVER['HTTP_HOST']
being empty in your PHP scripts.
This seemingly small issue has major consequences for applications that depend on knowing their hostname, particularly WordPress and similar CMS platforms.
The Solution: Explicitly Pass Host to PHP-FPM
Fortunately, the fix is straightforward. You need to explicitly set the HTTP_HOST
FastCGI parameter in your Nginx configuration to ensure it’s always passed to PHP, regardless of whether the request comes via HTTP/1.1, HTTP/2, or HTTP/3.
Step-by-Step Implementation
1. Locate your FastCGI parameters file
This is typically found at /etc/nginx/fastcgi_params
or included directly in your site configuration files. If you’re using a control panel like cPanel, Plesk, or CyberPanel, the location might differ.
2. Add the HTTP_HOST parameter
Open the file with your preferred text editor:
sudo nano /etc/nginx/fastcgi_params
Add this line to the file:
fastcgi_param HTTP_HOST $host;
If the file already contains a similar line, modify it to match the above.
3. Alternative: Site-specific implementation
If you prefer to make this change only for specific sites, you can add it directly to your site’s configuration block:
server {
listen 443 ssl http3;
# other server configs...
location ~ \.php$ {
# other fastcgi settings...
include fastcgi_params;
fastcgi_param HTTP_HOST $host;
}
}
4. Reload Nginx configuration
Apply your changes without downtime:
sudo systemctl reload nginx
Or, if using another distribution:
sudo nginx -s reload
5. Verify the fix
Create a simple PHP test file (e.g., info.php
) with the following content:
<?php
echo "HTTP_HOST: " . $_SERVER['HTTP_HOST'] . "<br>";
echo "SERVER_NAME: " . $_SERVER['SERVER_NAME'] . "<br>";
phpinfo();
?>
Access this file via your browser and verify that HTTP_HOST
is now properly set with your domain name.
Why Use $host
Instead of $http_host
?
This is a crucial distinction:
$host
is an internal Nginx variable that’s always populated, even when a client doesn’t send aHost
header or when using HTTP/3’s:authority
pseudo-header$http_host
directly maps to the client’sHost
header, which may be empty for HTTP/3 requests
By using $host
, you ensure consistent behavior across all HTTP protocols.
Common Issues and Troubleshooting
WordPress Still Redirecting Incorrectly
If you’re still experiencing issues after implementing the fix:
- Clear WordPress transients and caches
- Check for hardcoded domains in your database
- Verify your
wp-config.php
doesn’t have conflicting domain settings - Ensure your SSL configuration is correct
PHP-FPM Pool Configuration
Some setups may require additional configuration in your PHP-FPM pool:
env[HTTP_HOST] = $HTTP_HOST
Multiple Domain Setups
For WordPress multisite or other multi-domain configurations, this fix is even more critical. You should also verify that other crucial FastCGI parameters are properly set:
fastcgi_param SERVER_NAME $host;
fastcgi_param HTTPS on;
Performance Considerations
This fix has no measurable performance impact. The fastcgi_param
directive simply ensures that the already-available $host
value is properly passed to PHP-FPM.
Testing Your Implementation
To thoroughly test your fix:
- Access your site using HTTP/1.1, HTTP/2, and HTTP/3
- Test both with and without www prefix
- Test any subdomain configurations
- Verify WordPress admin functionality works correctly
- Check that permalinks and internal links include the proper domain
Conclusion
HTTP/3’s promising performance benefits shouldn’t come at the cost of breaking your PHP applications. By understanding how HTTP/3 handles headers differently and making this simple configuration adjustment, you can enjoy modern protocol benefits without sacrificing functionality.
The key takeaway: Always explicitly set fastcgi_param HTTP_HOST $host;
in your Nginx configuration when using HTTP/3 with PHP-FPM.
FAQ
Does this only affect WordPress?
No, this affects any PHP application that relies on the $_SERVER['HTTP_HOST']
variable, which includes most modern PHP frameworks and CMS platforms.
Will this be fixed in future Nginx versions?
While Nginx may improve HTTP/3 header handling in future releases, explicitly setting the HTTP_HOST
parameter is a reliable solution that works regardless of Nginx version.
Is this related to HTTP/3’s QUIC protocol?
Yes, HTTP/3’s fundamental architecture change from TCP to QUIC brings many improvements but also changes how headers are handled, leading to this specific issue.
Does this affect PHP-FPM performance?
No, this configuration change has no measurable impact on performance.
Should I apply this fix if I’m not using HTTP/3 yet?
Yes, it’s good practice to set this parameter regardless. It ensures consistent behavior when you do upgrade to HTTP/3 in the future.