How to Fix “Invalid HTTP_HOST Header” Error in Django/NGINX/Gunicorn Setup on AWS EC2


4 views

When working with Django, NGINX and Gunicorn on AWS EC2, you might encounter the frustrating "Invalid HTTP_HOST header" error. This typically occurs when:

  • The Host header doesn't match Django's ALLOWED_HOSTS setting
  • NGINX passes incorrect or malformed Host headers
  • Multiple Host headers are being sent

From your error messages, I can see several variants of the same core issue:

# Error 0 - Missing Host header
Invalid HTTP_HOST header: '/run/gunicorn.sock:'

# Error 1 - Duplicate host with port
Invalid HTTP_HOST header: '127.0.0.1:8000,127.0.0.1:8000'

# Error 2 - Inconsistent port usage
Invalid HTTP_HOST header: '127.0.0.1:8000,127.0.0.1'

# Error 3 - Server IP address issues
Invalid HTTP_HOST header: '13.234.187.18,13.234.187.18:8000'

The common pattern here is that Django is receiving improperly formatted or multiple Host headers, violating RFC 1034/1035 hostname standards.

Here's how to properly configure your setup end-to-end:

1. Django ALLOWED_HOSTS Configuration

First, ensure your Django settings.py has proper ALLOWED_HOSTS:

# settings.py
ALLOWED_HOSTS = [
    '13.234.187.18',  # Your EC2 public IP
    'localhost',
    '127.0.0.1',
    '.yourdomain.com'  # If using a domain
]

2. NGINX Configuration Fixes

Update your NGINX configuration to properly handle Host headers:

server {
    listen 8000;
    server_name 13.234.187.18;

    location / {
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
        proxy_buffering off;
        
        proxy_pass http://unix:/run/gunicorn.sock;
    }

    # Block invalid Host headers
    if ($host !~* ^(13.234.187.18|localhost|127.0.0.1)$ ) {
        return 444;
    }
}

3. Gunicorn Configuration

Ensure Gunicorn is properly bound to the Unix socket:

[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/gunicorn.sock
[Install]
WantedBy=sockets.target

For production environments, consider these extra protections:

# Django middleware to validate Host headers
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
USE_X_FORWARDED_HOST = True
SECURE_SSL_REDIRECT = True

If issues persist:

  1. Check NGINX error logs: sudo tail -f /var/log/nginx/error.log
  2. Verify Gunicorn is running: systemctl status gunicorn
  3. Test raw headers with curl: curl -v http://127.0.0.1:8000

When running a Django/DRF backend with Nginx and Gunicorn, you might encounter the "Invalid HTTP_HOST header" error. This typically occurs when:

  • Nginx passes incorrect Host headers to Gunicorn
  • Malformed requests reach your Django application
  • Your ALLOWED_HOSTS configuration is incomplete

From your description, we can see several variations of the error:

1. Invalid HTTP_HOST header: '/run/gunicorn.sock:'
2. Invalid HTTP_HOST header: '127.0.0.1:8000,127.0.0.1:8000'
3. Invalid HTTP_HOST header: '127.0.0.1:8000,127.0.0.1'
4. Invalid HTTP_HOST header: '13.234.187.18,13.234.187.18:8000'

Your current Nginx configuration needs several adjustments:

server {
    listen 8000;
    server_name yourdomain.com 13.234.187.18;

    location / {
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
        proxy_pass http://unix:/run/gunicorn.sock;
    }
}

Ensure your Django settings.py includes:

ALLOWED_HOSTS = [
    'yourdomain.com',
    '13.234.187.18',
    'localhost',
    '127.0.0.1'
]

To block invalid Host headers at the Nginx level:

server {
    listen 8000 default_server;
    server_name _;
    return 444;
}

server {
    listen 8000;
    server_name yourdomain.com 13.234.187.18;
    # ... rest of your config ...
}

Your Gunicorn service file should include proper binding:

[Unit]
Description=gunicorn daemon
After=network.target

[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/path/to/your/project
ExecStart=/path/to/gunicorn --workers 3 --bind unix:/run/gunicorn.sock yourproject.wsgi:application

[Install]
WantedBy=multi-user.target
  • Check Nginx error logs: sudo tail -f /var/log/nginx/error.log
  • Verify Gunicorn is running: ps aux | grep gunicorn
  • Test your configuration: sudo nginx -t
  • Restart services after changes: sudo systemctl restart nginx gunicorn

Remember to:

  1. Keep your server IP in ALLOWED_HOSTS only during development
  2. Use HTTPS in production
  3. Regularly update your server packages
  4. Implement proper firewall rules