400 Error, Bad Request when visiting domain name, IP address loads fine

July 1, 2015 15.7k views
Nginx DNS

Hi,
My website has been down for 2 months, I've basically given up resolving this issue, I have been talking with DO support as well as posting on stackoverflow and nobody seems to be able to help me.

Setup: 1-click install of django, ubuntu, nginx

Issue: After setting up a domain, visiting that domain results in a 400 error. visiting the IP works with no problem. I purchased the domain using Google Domains and used the custom name server option and put:

ns1.digitalocean.com
ns2.digitalocean.com
ns3.digitalocean.com

In etc/nginx/sites-available/django I have:

upstream app_server { 
server 127.0.0.1:9000 fail_timeout=0; 
}

server { 
listen 80 default_server; 
listen [::]:80 default_server ipv6only=on;

root /usr/share/nginx/html; 
index index.html index.htm;

client_max_body_size 4G; 
server_name cannablr.com www.cannablr.com;

keepalive_timeout 5;

# Your Django project's media files - amend as required 
location /media { 
alias /home/django/django/dealr/dealr/media; 
}

# your Django project's static files - amend as required 
location /static { 
alias /home/django/django/dealr/dealr/static; 
} 

location /favicon.ico { 
alias /home/django/django/dealr/favicon.ico; 
}

location / { 
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
proxy_set_header Host $http_host; 
proxy_redirect off; 
proxy_pass http://app_server; 
} 
}


I have this file symlinked inside etc/nginx/sites-enabled.

Another thing that may be worth noting is even though I get a 400 error when visiting the domain, it still loads the favicon.

Any ideas or help would be appreciated.
2 comments
  • OK, I think I've confirmed what I was hinting at.

    here's the headers when I curl by domain:

    user@host:~# curl -v cannablr.com
    * About to connect() to cannablr.com port 80 (#0)
    *   Trying 104.236.191.114... connected
    * Connected to cannablr.com (104.236.191.114) port 80 (#0)
    > GET / HTTP/1.1
    > User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.16.2.3 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2
    > Host: cannablr.com
    > Accept: */*
    >
    < HTTP/1.1 400 BAD REQUEST
    < Server: nginx/1.4.6 (Ubuntu)
    < Date: Wed, 01 Jul 2015 18:41:32 GMT
    < Content-Type: text/html
    < Transfer-Encoding: chunked
    < Connection: keep-alive
    <
    * Connection #0 to host cannablr.com left intact
    * Closing connection #0
    <h1>Bad Request (400)</h1>
    

    Now, when I go by IP:

     curl -v 104.236.191.114
    * About to connect() to 104.236.191.114 port 80 (#0)
    *   Trying 104.236.191.114... connected
    * Connected to 104.236.191.114 (104.236.191.114) port 80 (#0)
    > GET / HTTP/1.1
    > User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.16.2.3 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2
    > Host: 104.236.191.114
    > Accept: */*
    >
    < HTTP/1.1 200 OK
    < Server: nginx/1.4.6 (Ubuntu)
    < Date: Wed, 01 Jul 2015 18:41:47 GMT
    < Content-Type: text/html; charset=utf-8
    < Transfer-Encoding: chunked
    < Connection: keep-alive
    < Vary: Cookie
    <
    

    These 2 look similar, but very different when you realize the Content-Type is different and the IP-based one sets a cookie.

    The short answer is that you have 2 separate sites running on this thing.

    Let's run this to see if my theory pans out:

    find /etc/nginx/ -type f -name "*.conf" -print0 | xargs -0 egrep '^(\s|\t)*listen 80'
    
  • Hi, did you find out the solution to this? I'm having the same problem.

7 Answers

This has to do with getting ALLOWED_HOSTS correct.
ALLOWED_HOSTS: A list of strings representing the host/domain names that this Django site can serve
Ref: ALLOWED_HOSTS
Correct this in your setting file.
e.g. Django One-click app has settings location: /home/django/djangoproject/djangoproject/settings.py

  1. Add your domain to ALLOWED_HOSTS

    ALLOWED_HOSTS = ['example.com']
    
  2. At the end of file, one more entry exists for ALLOWED_HOSTS to allow sites to be accessed by DO ip addresses.

    # Discover our IP address
    ALLOWED_HOSTS = ip_addresses()
    

    Change "=" operator to "+=", so that it will append ip addresses rather than overwriting
    ALLOWED_HOSTS setting.

    # Discover our IP address
    ALLOWED_HOSTS += ip_addresses()
    
  3. If you don't want your Webapp to be accessed by ip address, simply comment/remove second entry.

You need to add your domain name to "ALLOWED_HOSTS' inside of "settings.py" of the django project

I believe I may have a solution. I was experiencing the same issue. I checked my settings.py file and at the very bottom I found

ALLOWED_HOSTS = ip_addresses()

I commented it out and everything appears to be working fine.

It seems that digital ocean has added this and the ip_addressses() function to the settings.py file but I do not have a clue as to why yet.

  • I think this just fixed the problem I've been dealing with for days! Thanks!
    1 click install... -.-

  • yes this works fine
    But after commenting out "ALLOWEDHOSTS = ipaddresses()" . you have to specify the domain name in the ALLOWED_HOSTS = ['example.com'] . you can add your IP here as well separate entries with comas.

  • yup that was my problem too, thanks very much!

Have you found an update to this problem? I have the exact same thing happening to me now.

i had the same problem but after following this instruction, ....Change "=" operator to "+=", so that it will append ip addresses rather than overwriting ALLOWED_HOSTS setting..., its stopped overwriting as explained
...thanks alot MeghaBodke

This was EXTREMELY helpful, thank you so much! Great explanation.

thank you !! that last line of code in the settings file that shipped with the one click install killed me.

Have another answer? Share your knowledge.