| | |

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 a Host header or when using HTTP/3’s :authority pseudo-header
  • $http_host directly maps to the client’s Host 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:

  1. Clear WordPress transients and caches
  2. Check for hardcoded domains in your database
  3. Verify your wp-config.php doesn’t have conflicting domain settings
  4. 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:

  1. Access your site using HTTP/1.1, HTTP/2, and HTTP/3
  2. Test both with and without www prefix
  3. Test any subdomain configurations
  4. Verify WordPress admin functionality works correctly
  5. 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.

Similar Posts