'How to fix nginx throws 400 bad request headers on any header testing tools?

I have my site which is using nginx, and testing site with header testing tools e.g. http://www.webconfs.com/http-header-check.php but every time it says 400 bad request below is the out put from the tool. Though all my pages load perfectly fine in browser and when I see in chrome console it says status code 200OK.

HTTP/1.1 400 Bad Request => 
Server => nginx
Date => Fri, 07 Sep 2012 09:40:09 GMT
Content-Type => text/html
Content-Length => 166
Connection => close

I really don't understand what is the problem with my server config?

A bit of googling suggests to increase the buffer size using, and I increased it to following:

large_client_header_buffers 4 16k;

The same results persist.

Can some one guide me to the right direction?



Solution 1:[1]

Yes changing the error_to debug level as Emmanuel Joubaud suggested worked out (edit /etc/nginx/sites-enabled/default ):

        error_log /var/log/nginx/error.log debug;

Then after restarting nginx I got in the error log with my Python application using uwsgi:

        2017/02/08 22:32:24 [debug] 1322#1322: *1 connect to unix:///run/uwsgi/app/socket, fd:20 #2
        2017/02/08 22:32:24 [debug] 1322#1322: *1 connected
        2017/02/08 22:32:24 [debug] 1322#1322: *1 http upstream connect: 0
        2017/02/08 22:32:24 [debug] 1322#1322: *1 posix_memalign: 0000560E1F25A2A0:128 @16
        2017/02/08 22:32:24 [debug] 1322#1322: *1 http upstream send request
        2017/02/08 22:32:24 [debug] 1322#1322: *1 http upstream send request body
        2017/02/08 22:32:24 [debug] 1322#1322: *1 chain writer buf fl:0 s:454
        2017/02/08 22:32:24 [debug] 1322#1322: *1 chain writer in: 0000560E1F2A0928
        2017/02/08 22:32:24 [debug] 1322#1322: *1 writev: 454 of 454
        2017/02/08 22:32:24 [debug] 1322#1322: *1 chain writer out: 0000000000000000
        2017/02/08 22:32:24 [debug] 1322#1322: *1 event timer add: 20: 60000:1486593204249
        2017/02/08 22:32:24 [debug] 1322#1322: *1 http finalize request: -4, "/?" a:1, c:2
        2017/02/08 22:32:24 [debug] 1322#1322: *1 http request count:2 blk:0
        2017/02/08 22:32:24 [debug] 1322#1322: *1 post event 0000560E1F2E5DE0
        2017/02/08 22:32:24 [debug] 1322#1322: *1 post event 0000560E1F2E5E40
        2017/02/08 22:32:24 [debug] 1322#1322: *1 delete posted event 0000560E1F2E5DE0
        2017/02/08 22:32:24 [debug] 1322#1322: *1 http run request: "/?"
        2017/02/08 22:32:24 [debug] 1322#1322: *1 http upstream check client, write event:1, "/"
        2017/02/08 22:32:24 [debug] 1322#1322: *1 http upstream recv(): -1 (11: Resource temporarily unavailable)

Then I took a look to my uwsgi log and found out that:

        Invalid HTTP_HOST header: 'www.mysite.local'. You may need to add u'www.mysite.local' to ALLOWED_HOSTS.
        [pid: 10903|app: 0|req: 2/4] 192.168.221.2 () {38 vars in 450 bytes} [Wed Feb  8 22:32:24 2017] GET / => generated 54098 bytes in 55 msecs (HTTP/1.1 400) 4 headers in 135 bytes (1 switches on core 0)

And adding www.mysite.local to the settings.py ALLOWED_HOSTS fixed the issue :)

        ALLOWED_HOSTS = ['www.mysite.local']

Solution 2:[2]

I had the same issue and tried everything. This 400 happened for an upstream proxy. Debug logged showed absolutely nothing.

The problem was in duplicate proxy_set_header Host $http_host directive, which I didn't notice initially. Removing duplicate one solved the issue immediately. I wish nginx was saying something other than 400 in this scenario, as nginx -t didn't complain at all.

P.S. this happened while migrating from older nginx 1.10 to the newer 1.19. Before it was tolerated apparently.

Solution 3:[3]

Just to clearify, in /etc/nginx/nginx.conf, you can put at the beginning of the file the line

error_log /var/log/nginx/error.log debug;

And then restart nginx:

sudo service nginx restart

That way you can detail what nginx is doing and why it is returning the status code 400.

Solution 4:[4]

A cause can be invalid encoding in the URL request. Such as % being passed un-encoded.

Solution 5:[5]

When nginx returns 400(bad request) it will log the reason into error log, at "info" level and take a look into error log when testing.

Solution 6:[6]

In my case, the issue was that port 443 wasn´t opened in the router

Solution 7:[7]

If you get log just like this:

client xx.xx.xx.xx closed keepalive connection 

For this issue:"Connection: upgrade" causes 400 error that never reaches application code. Triggered by common nginx config. #17081

just set proxy_set_header Connection $http_connection

Solution 8:[8]

normally, Maxim Donnie's method can find the reason. But I encountered one 400 bad request will not log to err_log. I found the reason with the help with tcpdump

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 John Difool
Solution 4 Martlark
Solution 5 Asdiana abd aziz
Solution 6 Lorenzo Lerate
Solution 7 ??0?
Solution 8 Dan