25

I've create a Django (1.7) web application with a Nginx, Gunicorn, Django stack and recently I've started to get a number of errors:

[Django] ERROR (EXTERNAL IP): Invalid HTTP_HOST header: '*.domain.com'. The domain name provided is not valid according to RFC 1034/1035.

After searching around, I've found several response that suggest putting the wildcard as the allowed hosts, i.e.

ALLOWED_HOSTS = ['*']

However I'm still getting this error.

Here is the full error message:

Request repr(): 
<WSGIRequest
path:/,
GET:<QueryDict: {}>,
POST:<QueryDict: {}>,
COOKIES:{},
META:{'HTTP_ACCEPT_ENCODING': 'none',
'HTTP_CONNECTION': 'close',
'HTTP_HOST': '*.domain.com',
'HTTP_USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.2)',
'HTTP_X_FORWARDED_FOR': '11.111.111.11',
'HTTP_X_FORWARDED_HOST': 'subdomain.domain.com',
'HTTP_X_REAL_IP': '11.111.111.11',
'PATH_INFO': u'/',
'QUERY_STRING': '',
'RAW_URI': '/',
'REMOTE_ADDR': '127.0.0.1',
'REMOTE_PORT': '51349',
'REQUEST_METHOD': 'GET',
'SCRIPT_NAME': u'',
'SERVER_NAME': '127.0.0.1',
'SERVER_PORT': '9000',
'SERVER_PROTOCOL': 'HTTP/1.0',
'SERVER_SOFTWARE': 'gunicorn/19.1.1',
'gunicorn.socket': <socket._socketobject object at 0x3877fa0>,
'wsgi.errors': <gunicorn.http.wsgi.WSGIErrorsWraper object at 0x37e6050>,
'wsgi.file_wrapper': <class 'gunicorn.http.wsgi.FileWrapper'>,
'wsgi.input': <gunicorn.http.body.Body object at 0x396cc50>,
'wsgi.multiprocess': False,
'wsgi.multithread': False,
'wsgi.run_once': False,
'wsgi.url_scheme': 'http',
'wsgi.version': (1, 0)}>

Is this something I should be concerned about? Am I missing something here? I thought by putting the wildcard in the allowed hosts, I would eliminate this issue, but that doesn't seem to be the case.

Any help would be much appreciated.

tdsymonds
  • 1,679
  • 1
  • 16
  • 26
  • 1
    I would not wildcard allowed hosts, instead use a list of the really allowed hosts like [www.domain.com, domain.com]. Also configure your Nginx to accept these requests via server_name. – Jingo Oct 13 '15 at 09:50
  • @Jingo thanks for your help and quick response. I had the domains added previously but encountered this same error, which is why I added the wildcard in it's place. Strange. I'll put it back as you've mentioned and see if I encounter these issues still. – tdsymonds Oct 13 '15 at 13:06
  • I've now removed the wildcard allowed hosts and still receiving this error?! – tdsymonds Oct 19 '15 at 16:22
  • Did you fix this? How? – Imran S. Mar 08 '16 at 03:21
  • No I didn't manage to fix unfortunately, however I believe it may be caused by an internal process that runs on our servers as it seems to happen at the same time every day :s – tdsymonds Mar 12 '16 at 09:13

4 Answers4

14

ISSUE: gunicorn (your Django App server) is getting an invalid host name.

when a request is made to the server (NginX) and the HTTP Host (or user agent) is empty, nginx sets the HTTP host to the gunicorn sock.


Solution: Add/update a directive in your nginx conf (nginx.conf or sites-enabled/<your-site>.conf) from:

proxy_set_header Host $http_host;

to (if you don't have it set, just add the following),

proxy_set_header Host $host;

Can put it inside the location, above the proxy_pass directive:

server {
    listen 8000;
    server_name 0.0.0.0;

    location / {
            proxy_set_header Host $host;
            include proxy_params;
            proxy_pass http://unix:/<your-path>/yourproject.sock;  

    }
}
Nabeel Ahmed
  • 18,328
  • 4
  • 58
  • 63
  • 3
    After adding this proxy_set_header in my file, Now I'm getting '400 bad request' on loading of my home page, – Siddaram H Dec 03 '18 at 18:55
  • 1
    Getting the 400 error message too. Had to remove it so fast. – tr33hous Jul 31 '20 at 09:50
  • 3
    Is `400` related to not having `proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;` in NGINX and not having `SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')` in Django settings ? – VivienG Aug 12 '20 at 11:15
  • oh dear this last comment was the fix to my more than 10 hours pain... – Escachator Oct 18 '20 at 22:17
  • after adding this, i got problems loading my django app (like, the csrf verification failure started happening, basically login itself stopped working) – Sowjanya R Bhat Jun 14 '22 at 17:47
4

The client that is making a request to your server has sent the following HTTP Host header:

Host: *.domain.com

This is invalid as per the HTTP specification - * is not allowed in the header - hence Django responds with a HTTP 400 response and logs the error.

This is not related to what you put in your ALLOWED_HOSTS setting, where * is permitted and tells Django to accept requests for any (valid) hostname (it will still reject invalid hostnames like *.domain.com).

As others have pointed out in the comments however, you should really configure nginx only to accept connections for specific hosts (server_name) so that such requests don't even reach Django.

solarissmoke
  • 30,039
  • 14
  • 71
  • 73
0

The problem for me causing this error was giving a non-standard domain name. (According to RFC 1034/1035). My domain had an underscore in it (like "example_domain.com").

I removed the _ and it worked!

Behnia FB
  • 53
  • 4
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 11 '23 at 09:36
-1

Instead of having following in settings.py, ALLOWED_HOSTS = ['*'] (Not a good practice in production)

Follow this - To respond to 'example.com' and any subdomains, start the domain with a dot ALLOWED_HOSTS = ['.example.com', '203.0.113.5']

Ambarish
  • 41
  • 1
  • 9