Ошибка 400 bad request nginx

Ошибка 400 bad request nginx означает, что сделан неверный запрос.

Ошибка может возникать по разным причинам, всё зависит от используемой конфигурации и приложения.

Если речь идет о запросах к базе данных или API — причина может быть в работе бэкенда. Например, недостаточное количество знаков в  поле БД.

В случае если ошибка возникает при обращении к странице сайта — причина обычно в Nginx и размерах буферов, которые задаются в конфигурационных файлах.

Рассмотрим подробнее этот случай, он самый типичный.

Ошибка 400 bad request nginx

Объем заголовков в запросе может быть различным. Если он велик и лимит, установленный в конфигурации, не позволяет их обработать — возникнет ошибка.

Ошибка исправляется добавлением в секцию http конфигурационного файла nginx.conf следующей директивы:

large_client_header_buffers 2 12k;

Тестируем конфигурацию, убеждаемся в том, что ошибок в выводе нет

nginx -t

Затем перечитываем конфигурация веб-сервера чтобы он увидел новые директивы и значения паратетров.

nginx -s reload

Если параметры уже добавлены можно попробовать увеличить их значения, в 2, в 4 раза.

С каждой итерацией нужно тестировать конфигурацию с помощью nginx -t, перезапускать процесс nginx -s reload и проверять выполняя тот же запрос при котором была ошибка 400 bad request nginx.

Дополнительно можно проверить логи Nginx

less /var/log/nginx/error.log

Если ошибка возникает периодически — в логе доступа можно найти при помощи grep все случаи получения ответа 400 по уникальным характеристикам запроса: комбинации даты, времени, ip адреса клиента. Затем сопоставить данные с записями в error.log — логе ошибок.

В access.log будут запросы, которые выполнялись при обращении к сайту.

Пример запроса с кодом ответа 400 приведен на скриншоте:

400 bad request nginx

Также есть другие буферы Nginx, на которые стоит обратить внимание (ссылка на статью про буферы была выше). Особенно если сервер обслуживает нагруженный проект.

Читайте про конфигурацию веб-сервера Nginx: структуру файлов с настройками и контексты.


Today I came across an interesting issue: A client got a http error 400 (bad request) when accessing certain pages of a website.

HTTP 400

This website’s architecture is built redundantly around a couple of load balancers. Here’s an example drawing of such an architecture:

Redundant web application architecture

This means the traffic needs to run through multiple hosts including Nginx and HAProxy servers until finally reaching the application itself on the application server or container.

Debugging in Nginx

Once the client’s IP address was identified I enabled the «debug mode» for this particular IP. Nginx allows to set a certain IP address or range into debug mode by using the «debug_connection» parameter in the events context. This context is usually found in /etc/nginx/nginx.conf:

events {
    # Debugging a certain IP
    debug_connection 192.168.55.12; # client getting http 400 errors
}

When this client accesses the website, there will be a lot of debug information written into the defined error log of the requested virtual host. So if you have a virtual host (server) config with a dedicated error log, this debugged connection will be logged there:

server {
  listen 80;
  server_name www.example.com;
  access_log  /var/log/nginx/www.example.com.access.log;
  error_log  /var/log/nginx/www.example.com.error.log;
[…]

The log entries appearing in /var/log/nginx/www.example.com.error.log will contain A LOT of information, don’t be shocked.

When I asked the client to access the website again and reproduce the http 400 error, this request was logged in detail and I was able to analyze it. Here’s the (almost) full data of that request:

2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http args: «»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http exten: «1482353»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http process request header line
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http header: «Host: www.example.com»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http header: «Connection: keep-alive»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http header: «Upgrade-Insecure-Requests: 1»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http header: «User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http header: «Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http header: «Referer: https://www.example.com/»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http header: «Accept-Encoding: gzip, deflate, br»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 posix_memalign: 00000000031BBA00:4096 @16
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http header: «Accept-Language: en-US,en;q=0.9,de;q=0.8»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http alloc large header buffer
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 malloc: 00000000031EDD50:8192
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http large header alloc: 00000000031EDD50 8192
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http large header copy: 464
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 SSL_read: 7140
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 SSL_read: -1
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 SSL_get_error: 2
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http header: «Cookie: bcjsck=defeb988-4e62-4971-b692-a0cab3e1aa15; bcjsmh=d41d8cd98f00b204e9800998ecf8427e; _ga=GA1.2.121262398.1500964581; conveyVisitorId=783533216391128700; _cb=DVtTO0D1nxaxqltf-; creid=1587323204948210394; ens_subscrptst=registered%3BTue%20Feb%2020%202018%2011%3A42%3A01%20GMT%2B0100%20(CET); _v__chartbeat3=CEFK3zDBkUfmBwsJ9l; _cb_ls=1; ivbsdid={«id»:»qsg6vkb6sb78″}; mbox=PC#9dc594f60e3f4c358006c402a9d0d73e.26_21#1604146991|session#61a773b682474005a1ba24467c023012#1542273057; _fbp=fb.1.1549266199618.647410032; __gads=ID=6456a71ef275ba00:T=1551781894:S=ALNI_MaKQ4DMVT2F6IMzm4G1dOcUA9koOg; ens_c1pid=8e3d2d2-4567-4074-abaf-2e6e5dc7c188; cresid_platform1234=cb81a3b283a9d208b04f7b5f6f548274; bclk=3704698032204732; cresid=6a7497a5ab3d809e8fb19644ad92e710; service=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjlmYzY2Zjg5LTdiM2ItNDBiYy04NDJhLTQzODNjMzZmMDJmYSJ9.eyJzZXJ2aWNlX2lkIjoibnp6IiwibG9naW4iOiJrYXRyaW4uaHV0aEBnbWFpbC5jb20iLCJsYXN0X25hbWUiOiJIdXRoIiwiZmlyc3RfbmFtZSI6IkthdHJpbiIsInNlc3Npb25faWQiOiJhYjU2YTYxMzg3MzYzYzZjNDM0NzIwODgxYzJjOGVkOCJ9.ZpC4f4fDN7yJT-QrsOj7CRFMxmmmZx-J08Vw8qHCpxCMlE5DJ97gn1vPmMomJhdU0JPrkHdJiAP5y-GRPRToz-1RUDhdeTmrZKHI6u9XrNDrDKUzWPxF553w2_O_TfD8ioTwLihn3sHhRpvAS7kLqbJCgMt5n3wB2Jbzz2mCVpfvFpyyMJoVDUTdeQ4Lefti-37wbwFHzZ-idt9rc3vYbK2iw0YTe-s7M3hsNRQ-2wFYSWjC4mAy8qtySa7Jb801eLSEqO2-W3603UkbcvjW9829-qn6kGrFjkEQ314I82HLgMX6Siy74BCVpPrOD-XLVNIwC_HX-6fknWkiXxR-Yg; ens_cntpvabo=383; ens_subscrst=subscriber%3BWed%20Jun%2026%202019%2009%3A48%3A49%20GMT%2B0200%20(Mitteleurop%C3%A4ische%20Sommerzeit); _gid=GA1.2.131606941.1558944578; ens_kavz=0986-0050-01-010; _fbc=fb.1.1558951120515.IwAR1vSVauTbRT1sO397XEXVmRHTSbC3dL08dZ9WSMVLGSoS4T9m8QRgHv6Js; p4m_snot=1318; s_vdnum=1559080800290%26vn%3D1; s_dinvisit=true; s_vwnum=1559426400501%26vn%3D7; s_winvisit=true; s_vmnum=1559340000345%26vn%3D56; s_minvisit=true; s_dslv_s=Less%20than%201%20day; ens_ueid_3425441984_513=1559034247693; ens_cntpwmt=5; ens_ueid_624612360_513=1559034320820; POPUPCHE
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http header done
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 generic phase: 0
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 rewrite phase: 1
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 test location: «/»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 test location: «sitemap»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 using configuration «/»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http cl:-1 max:104857600
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 rewrite phase: 3
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 post rewrite phase: 4
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 generic phase: 5
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 generic phase: 6
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 generic phase: 7
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 generic phase: 8
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 access phase: 9
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 access phase: 10
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 post access phase: 11
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http init upstream, client timer: 0
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 malloc: 0000000003207030:8282
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http script copy: «Host: «
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http script var: «www.example.com»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http script copy: «
«
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http script copy: «X-Real-IP: «
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http script var: «192.168.55.12»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http script copy: «
«
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http script copy: «X-Forwarded-For: «
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http script var: «192.168.55.12»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http script copy: «
«
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http script copy: «X-Forwarded-Proto: https
«
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http script copy: «Connection: close
«
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http script copy: «»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http script copy: «»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http script copy: «»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http script copy: «»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http proxy header: «Upgrade-Insecure-Requests: 1»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http proxy header: «User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http proxy header: «Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http proxy header: «Referer: https://www.example.com/»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http proxy header: «Accept-Encoding: gzip, deflate, br»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http proxy header: «Accept-Language: en-US,en;q=0.9,de;q=0.8»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http proxy header: «Cookie: bcjsck=defeb988-4e62-4971-b692-a0cab3e1aa15; bcjsmh=d41d8cd98f00b204e9800998ecf8427e; _ga=GA1.2.121262398.1500964581; conveyVisitorId=783533216391128700; _cb=DVtTO0D1nxaxqltf-; creid=1587323204948210394; ens_subscrptst=registered%3BTue%20Feb%2020%202018%2011%3A42%3A01%20GMT%2B0100%20(CET); _v__chartbeat3=CEFK3zDBkUfmBwsJ9l; _cb_ls=1; ivbsdid={«id»:»qsg6vkb6sb78″}; mbox=PC#9dc594f60e3f4c358006c402a9d0d73e.26_21#1604146991|session#61a773b682474005a1ba24467c023012#1542273057; _fbp=fb.1.1549266199618.647410032; __gads=ID=6456a71ef275ba00:T=1551781894:S=ALNI_MaKQ4DMVT2F6IMzm4G1dOcUA9koOg; ens_c1pid=8e3d2d2-4567-4074-abaf-2e6e5dc7c188; cresid_platform1234=cb81a3b283a9d208b04f7b5f6f548274; bclk=3704698032204732; cresid=6a7497a5ab3d809e8fb19644ad92e710; service=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjlmYzY2Zjg5LTdiM2ItNDBiYy04NDJhLTQzODNjMzZmMDJmYSJ9.eyJzZXJ2aWNlX2lkIjoibnp6IiwibG9naW4iOiJrYXRyaW4uaHV0aEBnbWFpbC5jb20iLCJsYXN0X25hbWUiOiJIdXRoIiwiZmlyc3RfbmFtZSI6IkthdHJpbiIsInNlc3Npb25faWQiOiJhYjU2YTYxMzg3MzYzYzZjNDM0NzIwODgxYzJjOGVkOCJ9.ZpC4f4fDN7yJT-QrsOj7CRFMxmmmZx-J08Vw8qHCpxCMlE5DJ97gn1vPmMomJhdU0JPrkHdJiAP5y-GRPRToz-1RUDhdeTmrZKHI6u9XrNDrDKUzWPxF553w2_O_TfD8ioTwLihn3sHhRpvAS7kLqbJCgMt5n3wB2Jbzz2mCVpfvFpyyMJoVDUTdeQ4Lefti-37wbwFHzZ-idt9rc3vYbK2iw0YTe-s7M3hsNRQ-2wFYSWjC4mAy8qtySa7Jb801eLSEqO2-W3603UkbcvjW9829-qn6kGrFjkEQ314I82HLgMX6Siy74BCVpPrOD-XLVNIwC_HX-6fknWkiXxR-Yg; ens_cntpvabo=383; ens_subscrst=subscriber%3BWed%20Jun%2026%202019%2009%3A48%3A49%20GMT%2B0200%20(Mitteleurop%C3%A4ische%20Sommerzeit); _gid=GA1.2.131606941.1558944578; ens_kavz=0986-0050-01-010; _fbc=fb.1.1558951120515.IwAR1vSVauTbRT1sO397XEXVmRHTSbC3dL08dZ9WSMVLGSoS4T9m8QRgHv6Js; p4m_snot=1318; s_vdnum=1559080800290%26vn%3D1; s_dinvisit=true; s_vwnum=1559426400501%26vn%3D7; s_winvisit=true; s_vmnum=1559340000345%26vn%3D56; s_minvisit=true; s_dslv_s=Less%20than%201%20day; ens_ueid_3425441984_513=1559034247693; ens_cntpwmt=5; ens_ueid_624612360_513=1559034320820; PO
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http proxy header:
«GET /news/article-1234.1482353 HTTP/1.0
Host: www.example.com
X-Real-IP: 192.168.55.12
X-Forwarded-For: 192.168.55.12
X-Forwarded-Proto: https
Connection: close
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Referer: https://www.example.com/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,de;q=0.8
Cookie: bcjsck=defeb988-4e62-4971-b692-a0cab3e1aa15; bcjsmh=d41d8cd98f00b204e9800998ecf8427e; _ga=GA1.2.121262398.1500964581; conveyVisitorId=783533216391128700; _cb=DVtTO0D1nxaxqltf-; creid=1587323204948210394; ens_subscrptst=registered%3BTue%20Feb%2020%202018%2011%3A42%3A01%20GMT%2B0100%20(CET); _v__chartbeat3=CEFK3zDBkUfmBwsJ9l; _cb_ls=1; ivbsdid={«id»:»qsg6vkb6sb78″}; mbox=PC#9dc594f60e3f4c358006c402a9d0d73e.26_21#1604146991|session#61a773b682474005a1ba24467c023012#1542273057; _fbp=fb.1.1549266199618.647410032; __gads=ID=6456a71ef275ba00:T=1551781894:S=ALNI_MaKQ4DMVT2F6IMzm4G1dOcUA9koOg; ens_c1pid=8e3d2d2-4567-4074-abaf-2e6e5dc7c188; cresid_platform1234=cb81a3b283a9d208b04f7b5f6f548274; bclk=3704698032204732; cresid=6a7497a5ab3d809e8fb19644ad92e710; service=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjlmYzY2Zjg5LTdiM2ItNDBiYy04NDJhLTQzODNjMzZmMDJmYSJ9.eyJzZXJ2aWNlX2lkIjoibnp6IiwibG9naW4iOiJrYXRyaW4uaHV0aEBnbWFpbC5jb20iLCJsYXN0X25hbWUiOiJIdXRoIiwiZmlyc3RfbmFtZSI6IkthdHJpbiIsInNlc3Npb25faWQiOiJhYjU2YTYxMzg3MzYzYzZjNDM0NzIwODgxYzJjOGVkOCJ9.ZpC4f4fDN7yJT-QrsOj7CRFMxmmmZx-J08Vw8qHCpxCMlE5DJ97gn1vPmMomJhdU0JPrkHdJiAP5y-GRPRToz-1RUDhdeTmrZKHI6u9XrNDrDKUzWPxF553w2_O_TfD8ioTwLihn3sHhRpvAS7kLqbJCgMt5n3wB2Jbzz2mCVpfvFpyyMJoVDUTdeQ4Lefti-37wbwFHzZ-idt9rc3vYbK2iw0YTe-s7M3hsNRQ-2wFYSWjC4mAy8qtySa7Jb801eLSEqO2-W3603UkbcvjW
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http cleanup add: 00000000031BC128
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 get rr peer, try: 1
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 stream socket 1514
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 epoll add connection: fd:1514 ev:80002005
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 connect to 127.0.0.1:8080, fd:1514 #1706804565
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http upstream connect: -2
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 posix_memalign: 00000000021EF490:128 @16
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 event timer add: 1514: 6000000:1559039102955
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http finalize request: -4, «/news/article-1234.1482353?» a:1, c:2
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http request count:2 blk:0
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 delete posted event 00007F5DB055BA50
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http run request: «/news/article-1234.1482353?»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http upstream check client, write event:1, «/news/article-1234.1482353»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http upstream recv(): -1 (11: Resource temporarily unavailable)
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 post event 00007F5DB055BA50
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 post event 00007F5DB055B210
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 delete posted event 00007F5DB055BA50
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http run request: «/news/article-1234.1482353?»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http upstream check client, write event:1, «/news/article-1234.1482353»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http upstream recv(): -1 (11: Resource temporarily unavailable)
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 delete posted event 00007F5DB055B210
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http upstream request: «/news/article-1234.1482353?»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http upstream send request handler
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http upstream send request
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http upstream send request body
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 chain writer buf fl:1 s:8243
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 chain writer in: 00000000031BC160
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 writev: 8243 of 8243
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 chain writer out: 0000000000000000
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 event timer del: 1514: 1559039102955
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 event timer add: 1514: 6000000:1559039102959
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 post event 00007F5DB064C210
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 post event 00007F5DB055B210
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 delete posted event 00007F5DB064C210
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http upstream request: «/news/article-1234.1482353?»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http upstream process header
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 malloc: 000000000318A3F0:4096
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 recv: fd:1514 187 of 4096
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http proxy status 400 «400 Bad request»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http proxy header: «Cache-Control: no-cache»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http proxy header: «Connection: close»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http proxy header: «Content-Type: text/html»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http proxy header done
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 HTTP/1.1 400 Bad request
Server: nginx/1.10.2
Date: Tue, 28 May 2019 08:45:02 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: no-cache

There’s obviously a lot of data and it’s not easy to find the relevant part. I try to cherry-pick the relevant lines:

2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http header: «Accept-Language: en-US,en;q=0.9,de;q=0.8»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http alloc large header buffer
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 malloc: 00000000031EDD50:8192
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http large header alloc: 00000000031EDD50 8192
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http large header copy: 464
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 SSL_read: 7140
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 SSL_read: -1
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 SSL_get_error: 2
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http header: «Cookie: bcjsck=defeb988-4e62-4971-b692-a0cab3e1aa15; bcjsmh=d41d8cd98f00b204e9800998ecf8427e; _ga=GA1.2.121262398.1500964581; conveyVisitorId=783533216391128700; _cb=DVtTO0D1nxaxqltf-; creid=1587323204948210394; ens_subscrptst=registered%3BTue%20Feb%2020%202018%2011%3A42%3A01%20GMT%2B0100%20(CET); _v__chartbeat3=CEFK3zDBkUfmBwsJ9l; _cb_ls=1; ivbsdid={«id»:»qsg6vkb6sb78″}; mbox=PC#9dc594f60e3f4c358006c402a9d0d73e.26_21#1604146991|session#61a773b682474005a1ba24467c023012#1542273057; _fbp=fb.1.1549266199618.647410032; __gads=ID=6456a71ef275ba00:T=1551781894:S=ALNI_MaKQ4DMVT2F6IMzm4G1dOcUA9koOg; ens_c1pid=8e3d2d2-4567-4074-abaf-2e6e5dc7c188; cresid_platform1234=cb81a3b283a9d208b04f7b5f6f548274; bclk=3704698032204732; cresid=6a7497a5ab3d809e8fb19644ad92e710; service=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjlmYzY2Zjg5LTdiM2ItNDBiYy04NDJhLTQzODNjMzZmMDJmYSJ9.eyJzZXJ2aWNlX2lkIjoibnp6IiwibG9naW4iOiJrYXRyaW4uaHV0aEBnbWFpbC5jb20iLCJsYXN0X25hbWUiOiJIdXRoIiwiZmlyc3RfbmFtZSI6IkthdHJpbiIsInNlc3Npb25faWQiOiJhYjU2YTYxMzg3MzYzYzZjNDM0NzIwODgxYzJjOGVkOCJ9.ZpC4f4fDN7yJT-QrsOj7CRFMxmmmZx-J08Vw8qHCpxCMlE5DJ97gn1vPmMomJhdU0JPrkHdJiAP5y-GRPRToz-1RUDhdeTmrZKHI6u9XrNDrDKUzWPxF553w2_O_TfD8ioTwLihn3sHhRpvAS7kLqbJCgMt5n3wB2Jbzz2mCVpfvFpyyMJoVDUTdeQ4Lefti-37wbwFHzZ-idt9rc3vYbK2iw0YTe-s7M3hsNRQ-2wFYSWjC4mAy8qtySa7Jb801eLSEqO2-W3603UkbcvjW9829-qn6kGrFjkEQ314I82HLgMX6Siy74BCVpPrOD-XLVNIwC_HX-6fknWkiXxR-Yg; ens_cntpvabo=383; ens_subscrst=subscriber%3BWed%20Jun%2026%202019%2009%3A48%3A49%20GMT%2B0200%20(Mitteleurop%C3%A4ische%20Sommerzeit); _gid=GA1.2.131606941.1558944578; ens_kavz=0986-0050-01-010; _fbc=fb.1.1558951120515.IwAR1vSVauTbRT1sO397XEXVmRHTSbC3dL08dZ9WSMVLGSoS4T9m8QRgHv6Js; p4m_snot=1318; s_vdnum=1559080800290%26vn%3D1; s_dinvisit=true; s_vwnum=1559426400501%26vn%3D7; s_winvisit=true; s_vmnum=1559340000345%26vn%3D56; s_minvisit=true; s_dslv_s=Less%20than%201%20day; ens_ueid_3425441984_513=1559034247693; ens_cntpwmt=5; ens_ueid_624612360_513=1559034320820; POPUPCHE
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http header done

Nginx detected a large HTTP header and allocated a buffer for it.  Especially the «Cookie» header is huge and contains a lot of cookies and their session data.

A bit further down, the same headers are sent to the upstream server (the next hop in the data flow) using the «proxy» module:

2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http proxy header: «Accept-Language: en-US,en;q=0.9,de;q=0.8»
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http proxy header: «Cookie: bcjsck=defeb988-4e62-4971-b692-a0cab3e1aa15; bcjsmh=d41d8cd98f00b204e9800998ecf8427e; _ga=GA1.2.121262398.1500964581; conveyVisitorId=783533216391128700; _cb=DVtTO0D1nxaxqltf-; creid=1587323204948210394; ens_subscrptst=registered%3BTue%20Feb%2020%202018%2011%3A42%3A01%20GMT%2B0100%20(CET); _v__chartbeat3=CEFK3zDBkUfmBwsJ9l; _cb_ls=1; ivbsdid={«id»:»qsg6vkb6sb78″}; mbox=PC#9dc594f60e3f4c358006c402a9d0d73e.26_21#1604146991|session#61a773b682474005a1ba24467c023012#1542273057; _fbp=fb.1.1549266199618.647410032; __gads=ID=6456a71ef275ba00:T=1551781894:S=ALNI_MaKQ4DMVT2F6IMzm4G1dOcUA9koOg; ens_c1pid=8e3d2d2-4567-4074-abaf-2e6e5dc7c188; cresid_platform1234=cb81a3b283a9d208b04f7b5f6f548274; bclk=3704698032204732; cresid=6a7497a5ab3d809e8fb19644ad92e710; service=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjlmYzY2Zjg5LTdiM2ItNDBiYy04NDJhLTQzODNjMzZmMDJmYSJ9.eyJzZXJ2aWNlX2lkIjoibnp6IiwibG9naW4iOiJrYXRyaW4uaHV0aEBnbWFpbC5jb20iLCJsYXN0X25hbWUiOiJIdXRoIiwiZmlyc3RfbmFtZSI6IkthdHJpbiIsInNlc3Npb25faWQiOiJhYjU2YTYxMzg3MzYzYzZjNDM0NzIwODgxYzJjOGVkOCJ9.ZpC4f4fDN7yJT-QrsOj7CRFMxmmmZx-J08Vw8qHCpxCMlE5DJ97gn1vPmMomJhdU0JPrkHdJiAP5y-GRPRToz-1RUDhdeTmrZKHI6u9XrNDrDKUzWPxF553w2_O_TfD8ioTwLihn3sHhRpvAS7kLqbJCgMt5n3wB2Jbzz2mCVpfvFpyyMJoVDUTdeQ4Lefti-37wbwFHzZ-idt9rc3vYbK2iw0YTe-s7M3hsNRQ-2wFYSWjC4mAy8qtySa7Jb801eLSEqO2-W3603UkbcvjW9829-qn6kGrFjkEQ314I82HLgMX6Siy74BCVpPrOD-XLVNIwC_HX-6fknWkiXxR-Yg; ens_cntpvabo=383; ens_subscrst=subscriber%3BWed%20Jun%2026%202019%2009%3A48%3A49%20GMT%2B0200%20(Mitteleurop%C3%A4ische%20Sommerzeit); _gid=GA1.2.131606941.1558944578; ens_kavz=0986-0050-01-010; _fbc=fb.1.1558951120515.IwAR1vSVauTbRT1sO397XEXVmRHTSbC3dL08dZ9WSMVLGSoS4T9m8QRgHv6Js; p4m_snot=1318; s_vdnum=1559080800290%26vn%3D1; s_dinvisit=true; s_vwnum=1559426400501%26vn%3D7; s_winvisit=true; s_vmnum=1559340000345%26vn%3D56; s_minvisit=true; s_dslv_s=Less%20than%201%20day; ens_ueid_3425441984_513=1559034247693; ens_cntpwmt=5; ens_ueid_624612360_513=1559034320820; PO
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http proxy header:
«GET /news/article-1234.1482353 HTTP/1.0

Finally the upstream server returned a HTTP 400 error when the proxied http headers were parsed:

2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http upstream process header
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 malloc: 000000000318A3F0:4096
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 recv: fd:1514 187 of 4096
2019/05/28 10:45:02 [debug] 14311#0: *1706803906 http proxy status 400 «400 Bad request»

By taking a closer look at the «Cookie» header from the http request, the data seems to be cut. It ends with «POPUPCHE» and does not contain a value.

Furthermore the Cookie header was even more cut when the request was forwarded to the upstream server; it ends with just «PO».

Obviously these request headers are too big to handle for Nginx and they are cut to a default size. The default header size limit in Nginx is 8K.

Adjust Nginx to allow larger http headers

The HTTP protocol itself does not define a size limit of the headers, but for security and performance reasons these limits are (usually) set in the web servers. These default limits can be changed, of course.

In Nginx this default size can be changed using the option «large_client_header_buffers». You can set this either globally in the «http» context or in a «server» context for a specific vhost. In this example I set a new limit of 64K in the «http» context:

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    # Allow larger than normal headers
    large_client_header_buffers 4 64k;
[…]

Followed by a Nginx reload, the new http header size limit should be activated.

Testing and failing again

Now that Nginx was told to accept the larger headers, I asked the client to reproduce the error. And the http 400 error occurred again. Once more, I checked the debug logs:

2019/05/28 11:00:57 [debug] 20067#0: *1707128584 http large header alloc: 00000000036E84F0 65536
2019/05/28 11:00:57 [debug] 20067#0: *1707128584 http large header copy: 499
2019/05/28 11:00:57 [debug] 20067#0: *1707128584 SSL_read: 7257
2019/05/28 11:00:57 [debug] 20067#0: *1707128584 SSL_read: -1
2019/05/28 11:00:57 [debug] 20067#0: *1707128584 SSL_get_error: 2
2019/05/28 11:00:57 [debug] 20067#0: *1707128584 posix_memalign: 00000000036A2010:4096 @16
2019/05/28 11:00:57 [debug] 20067#0: *1707128584 http header: «Cookie: bcjsck=defeb988-4e62-4971-b692-a0cab3e1aa15; bcjsmh=d41d8cd98f00b204e9800998ecf8427e; _ga=GA1.2.121262398.1500964581; conveyVisitorId=783533216391128700; _cb=DVtTO0D1nxaxqltf-; creid=1587323204948210394; ens_subscrptst=registered%3BTue%20Feb%2020%202018%2011%3A42%3A01%20GMT%2B0100%20(CET); _v__chartbeat3=CEFK3zDBkUfmBwsJ9l; _cb_ls=1; ivbsdid={«id»:»qsg6vkb6sb78″}; mbox=PC#9dc594f60e3f4c358006c402a9d0d73e.26_21#1604146991|session#61a773b682474005a1ba24467c023012#1542273057; _fbp=fb.1.1549266199618.647410032; __gads=ID=6456a71ef275ba00:T=1551781894:S=ALNI_MaKQ4DMVT2F6IMzm4G1dOcUA9koOg; ens_c1pid=8e094fdb-0241-4074-abaf-2e6e5dc7c188; cresid_platform1234=cb81a3b283a9d208b04f7bf803883d4c; bclk=3704698032204732; cresid=6a7497a5ab3d809e8fb19644ad92e710; service=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjlmYzY2Zjg5LTdiM2ItNDBiYy04NDJhLTQzODNjMzZmMDJmYSJ9.eyJzZXJ2aWNlX2lkIjoibnp6IiwibG9naW4iOiJrYXRyaW4uaHV0aEBnbWFpbC5jb20iLCJsYXN0X25hbWUiOiJIdXRoIiwiZmlyc3RfbmFtZSI6IkthdHJpbiIsInNlc3Npb25faWQiOiJhYjU2YTYxMzg3MzYzYzZjNDM0NzIwODgxYzJjOGVkOCJ9.ZpC4f4fDN7yJT-QrsOj7CRFMxmmmZx-J08Vw8qHCpxCMlE5DJ97gn1vPmMomJhdU0JPrkHdJiAP5y-GRPRToz-1RUDhdeTmrZKHI6u9XrNDrDKUzWPxF553w2_O_TfD8ioTwLihn3sHhRpvAS7kLqbJCgMt5n3wB2Jbzz2mCVpfvFpyyMJoVDUTdeQ4Lefti-37wbwFHzZ-idt9rc3vYbK2iw0YTe-s7M3hsNRQ-2wFYSWjC4mAy8qtySa7Jb801eLSEqO2-W3603UkbcvjW9829-qn6kGrFjkEQ314I82HLgMX6Siy74BCVpPrOD-XLVNIwC_HX-6fknWkiXxR-Yg; ens_cntpvabo=383; ens_subscrst=subscriber%3BWed%20Jun%2026%202019%2009%3A48%3A49%20GMT%2B0200%20(Mitteleurop%C3%A4ische%20Sommerzeit); _gid=GA1.2.131606941.1558944578; ens_kavz=0986-0050-01-010; _fbc=fb.1.1558951120515.IwAR1vSVauTbRT1sO397XEXVmRHTSbC3dL08dZ9WSMVLGSoS4T9m8QRgHv6Js; p4m_snot=1318; s_vdnum=1559080800290%26vn%3D1; s_dinvisit=true; s_vwnum=1559426400501%26vn%3D7; s_winvisit=true; s_vmnum=1559340000345%26vn%3D56; s_minvisit=true; s_dslv_s=Less%20than%201%20day; ens_ueid_3425441984_513=1559034247693; ens_ueid_624612360_513=1559034320820; POPUPCHECK=155911712556
2019/05/28 11:00:57 [debug] 20067#0: *1707128584 http header done

This time the received «Cookie» header was complete!

Also the full «Cookie» header was sent to the upstream server:

2019/05/28 11:00:57 [debug] 20067#0: *1707128584 http proxy header: «Cookie: bcjsck=defeb988-4e62-4971-b692-a0cab3e1aa15; bcjsmh=d41d8cd98f00b204e9800998ecf8427e; _ga=GA1.2.121262398.1500964581; conveyVisitorId=783533216391128700; _cb=DVtTO0D1nxaxqltf-; creid=1587323204948210394; ens_subscrptst=registered%3BTue%20Feb%2020%202018%2011%3A42%3A01%20GMT%2B0100%20(CET); _v__chartbeat3=CEFK3zDBkUfmBwsJ9l; _cb_ls=1; ivbsdid={«id»:»qsg6vkb6sb78″}; mbox=PC#9dc594f60e3f4c358006c402a9d0d73e.26_21#1604146991|session#61a773b682474005a1ba24467c023012#1542273057; _fbp=fb.1.1549266199618.647410032; __gads=ID=6456a71ef275ba00:T=1551781894:S=ALNI_MaKQ4DMVT2F6IMzm4G1dOcUA9koOg; ens_c1pid=8e094fdb-0241-4074-abaf-2e6e5dc7c188; cresid_platform1234=cb81a3b283a9d208b04f7bf803883d4c; bclk=3704698032204732; cresid=6a7497a5ab3d809e8fb19644ad92e710; service=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjlmYzY2Zjg5LTdiM2ItNDBiYy04NDJhLTQzODNjMzZmMDJmYSJ9.eyJzZXJ2aWNlX2lkIjoibnp6IiwibG9naW4iOiJrYXRyaW4uaHV0aEBnbWFpbC5jb20iLCJsYXN0X25hbWUiOiJIdXRoIiwiZmlyc3RfbmFtZSI6IkthdHJpbiIsInNlc3Npb25faWQiOiJhYjU2YTYxMzg3MzYzYzZjNDM0NzIwODgxYzJjOGVkOCJ9.ZpC4f4fDN7yJT-QrsOj7CRFMxmmmZx-J08Vw8qHCpxCMlE5DJ97gn1vPmMomJhdU0JPrkHdJiAP5y-GRPRToz-1RUDhdeTmrZKHI6u9XrNDrDKUzWPxF553w2_O_TfD8ioTwLihn3sHhRpvAS7kLqbJCgMt5n3wB2Jbzz2mCVpfvFpyyMJoVDUTdeQ4Lefti-37wbwFHzZ-idt9rc3vYbK2iw0YTe-s7M3hsNRQ-2wFYSWjC4mAy8qtySa7Jb801eLSEqO2-W3603UkbcvjW9829-qn6kGrFjkEQ314I82HLgMX6Siy74BCVpPrOD-XLVNIwC_HX-6fknWkiXxR-Yg; ens_cntpvabo=383; ens_subscrst=subscriber%3BWed%20Jun%2026%202019%2009%3A48%3A49%20GMT%2B0200%20(Mitteleurop%C3%A4ische%20Sommerzeit); _gid=GA1.2.131606941.1558944578; ens_kavz=0986-0050-01-010; _fbc=fb.1.1558951120515.IwAR1vSVauTbRT1sO397XEXVmRHTSbC3dL08dZ9WSMVLGSoS4T9m8QRgHv6Js; p4m_snot=1318; s_vdnum=1559080800290%26vn%3D1; s_dinvisit=true; s_vwnum=1559426400501%26vn%3D7; s_winvisit=true; s_vmnum=1559340000345%26vn%3D56; s_minvisit=true; s_dslv_s=Less%20than%201%20day; ens_ueid_3425441984_513=1559034247693; ens_ueid_624612360_513=1559034320820; POPUPCHECK=155911

But the upstream server still sent back a 400 error:

2019/05/28 11:00:57 [debug] 20067#0: *1707128584 http upstream process header
2019/05/28 11:00:57 [debug] 20067#0: *1707128584 malloc: 00000000034EB2E0:4096
2019/05/28 11:00:57 [debug] 20067#0: *1707128584 recv: fd:379 187 of 4096
2019/05/28 11:00:57 [debug] 20067#0: *1707128584 http proxy status 400 «400 Bad request»

Why would that be?

When you look at the architecture drawing at the begin, you see that after the Nginx web server, the next hop of the dataflow is HAProxy. And because HAProxy is also (kind of) a HTTP server, there are also some defaults and limits to be considered.

Adjust HAProxy to allow larger http headers

HAProxy has a lot of fine tuning settings. And to allow larger http headers, we need to exactly tune these.

The relevant settings are tune.bufsize and tune.maxrewrite. It’s important to set both of these, as the documentation says:

tune.bufsize sets the buffer size to this size (in bytes). The default value is 16384 and can be changed at build time. […] If HTTP request is larger than (tune.bufsize — tune.maxrewrite), haproxy will return HTTP 400 (Bad Request) error. Similarly if an HTTP response is larger than this size, haproxy will return HTTP 502 (Bad Gateway).

Both of these options need to be set in the «global» section of your HAProxy config:

#———————————————————————
# Global settings
#———————————————————————
global
    log /dev/log    local0
    log /dev/log    local1 notice
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    user haproxy
    group haproxy
    daemon

    # Default SSL material locations
    ca-base /etc/ssl/certs
    crt-base /etc/ssl/private

    # Default ciphers to use on SSL-enabled listening sockets.
    # For more information, see ciphers(1SSL). This list is from:
    #  https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
    ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
    ssl-default-bind-options no-sslv3

    # Large Buffer Sizes (to allow larger http headers/requests)
    tune.maxrewrite 16384
    tune.bufsize 65535

In this case a buffer size of 64K and a max rewrite size of 16K is defined. Which leaves us with a limit size of 48K.

Let’s see if this is enough for our client.

After reloading HAProxy, the new limits are in place.

Party time

The next request came in shortly and this time the response was a successful HTTP 200:

2019/05/28 11:42:35 [debug] 20067#0: *1708050081 http upstream process header
2019/05/28 11:42:35 [debug] 20067#0: *1708050081 malloc: 00000000031B8E50:4096
2019/05/28 11:42:35 [debug] 20067#0: *1708050081 recv: fd:884 4096 of 4096
2019/05/28 11:42:35 [debug] 20067#0: *1708050081 http proxy status 200 «200 OK»

Finally the 400 errors are gone and it was all due to a larger than usual http request, because of the large http headers (damn cookies!).

If you need to increase the request/header limits, it’s important to do this in the whole chain of dataflow. Every http/application server this request goes through must be checked and if necessary adjusted.

A handy comparison of defaults

To finalize this posts, here are the default values for request/header size limits of some http servers, as of February 2021 (last updated):

 HTTP Server    Setting / Option name   Default value 
 Apache 2.2 LimitRequestFieldSize  8190
 Apache 2.4 LimitRequestFieldSize  8190
 HAProxy tune.bufsize / tune.maxrewrite  16384 / half of bufsize
 IIS 4.x MaxClientRequestBuffer  2M
 IIS 5.x MaxClientRequestBuffer  128K
 IIS 5.x w Win 2000 SP4  MaxClientRequestBuffer  16K
 IIS 6.x and later MaxRequestBytes  16K
 Lighttpd server.max-request-field-size  none
 LiteSpeed maxReqHeaderSize  16380
 Nginx large_client_header_buffers  4 8k
 Node.js < v13.13.0 —max-http-header-size  8KB
 Node.js >= v13.13.0 —max-http-header-size  16KB
 Tomcat 5.5 maxHttpHeaderSize  4096
 Tomcat 6 and later maxHttpHeaderSize  8192
 Wildfly 10 and later max-header-size  1048576

Meanwhile Geeker’s Digest also published an up to date list of HTTP request header limits.

Add a comment

Show form to leave a comment

Comments (newest first)

Ali from India wrote on May 29th, 2022:

Thanks for detailed explanation. I like who share real outputs and explain each step-by-step. Solved my issue with this!!

Thank you!


Ошибка 400 Bad Request возникает, когда сервер не может понять запрос, отправленный клиентом. В вашем случае это может быть связано с тем, что настройки сервера не соответствуют запросу.

Судя по коду из вашего nginx.conf, вы пытаетесь перенаправить HTTP-запросы на HTTPS-порт с помощью rewrite. Однако вместо этого запросы на порт 8080 проксируются на другой сервер.

Для исправления проблемы с ошибкой 400 вам нужно изменить ваш nginx.conf, чтобы он правильно перенаправлял HTTP-запросы на HTTPS-порт.

Примерно так должно выглядеть ваш nginx.conf:

server {
    listen 80;
    server_name example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/cert.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    location / {
        root /var/www/example.com/;
        index index.html;
    }

    location /server/ {
        resolver 00.000.000.00;
        proxy_pass https://00.000.000.00;
    }
}

Этот конфигурационный файл перенаправляет все запросы на порт 80 (HTTP) на порт 443 (HTTPS) с помощью return 301. Затем он обрабатывает запросы на порт 443 (HTTPS), предоставляя файлы из каталога /var/www/example.com/ для пути / и проксируя запросы на путь /server/ на другой сервер.

Убедитесь, что после внесения изменений вы перезапустили сервер NGINX с помощью команды
sudo systemctl restart nginx.

How to solve 400 bad request error when using nginx as reverse proxy ?

Problem

The original nginx.conf file content

http { 
  upstream myserver {
    server 127.0.0.1:8001;
    server 127.0.0.1:8002;
    server 127.0.0.1:8003;
  }

  server {
    listen 8000;
    server_name 127.0.0.1;
    location / {
      proxy_pass http://myserver;
    }
  }
}

I run three http server instances in one server, and I use nginx as reverse proxy to load balancing the request to backend http services.

image-20200910145002711

When I start nginx, I got this:

HTTP/1.1 400 Bad Request => 
Server => nginx

I use curl to debug the http request and response:

curl -v http://127.0.0.1:8000/
    *   Trying 127.0.0.1...
    * TCP_NODELAY set
    * Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)
    > GET / HTTP/1.1
    > Host: 127.0.0.1:8000
    >
    < HTTP/1.1 400 Bad Request
    < Server: nginx
    ....
    <
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
    <HTML><HEAD><TITLE>Bad Request</TITLE>
    <META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
    <BODY><h2>Bad Request</h2>
    <hr><p>HTTP Error 400.</p>
    </BODY></HTML>

Solution #1

When nginx returns 400 (Bad Request) it will log the reason into error log, at “info” level. Hence an obvious way to find out what’s going on is to configure error_log to log messages at “info” level and take a look into error log when testing.

You should open the debug log by adding this line to nginx.conf:

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

Solution #2

Some server may require additional http headers to be set in the http request. You can add some useful http headers by using proxy_set_header like this:

proxy_set_header Host      $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

According to mozilla document:

The Host Header Specifies the domain name of the server (for virtual hosting), and (optionally) the TCP port number on which the server is listening.

X-Real-IP Let nginx pass the request to backend with real client IP address. You should know that:

This module is not built by default, it should be enabled with the --with-http_realip_module configuration parameter.

X-Forwarded-For Identifies the originating IP addresses of a client connecting to a web server through an HTTP proxy or a load balancer.

The final nginx.conf

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

http {
    upstream myserver {
        server 127.0.0.1:8001;
        server 127.0.0.1:8002;
        server 127.0.0.1:8003;
    }
    server {
        listen       8000;
        server_name  127.0.0.1;

        location / {
           proxy_pass http://myserver/;

           proxy_set_header Host      $host:$server_port;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	       
        }
      }
}

Navigating the murky waters of 400 bad request nginx errors can feel daunting, especially when disrupting your site’s functionality. However, understanding the interplay between HTTP headers, the infamous nginx 400 bad request SSL, and the elusive nginx 400 157 issues can significantly enhance your troubleshooting prowess.400 Bad Request Nginx

And yes, we’ll also untangle the complexities of cloudflare 400 bad request errors to ensure that all these glitches become less of a mystery. This is a deep dive into deciphering these nettlesome notifications – buckle up because it will be an enlightening journey!

Contents

  • Why Is the 400 Bad Request Nginx Code Exception Happening?
    • – Non-Encrypted Request Is Sent To An Encrypted Port
    • – Amiss With The Data You Are Sending
    • – Proxy Server Issues Between The Client and Server
  • How to Fix the 400 Bad Request Nginx Code Exception?
    • – Check The Syntax of Your Request
    • – Ensure You Use The Correct URL
    • – Clear Your Browser’s Cookies And Cache
  • Conclusion

Why Is the 400 Bad Request Nginx Code Exception Happening?

The 400 Bad Request on Kindle code usually happens when there’s a client-side issue. For example, this could be due to malformed syntax in the HTTP request, an incorrect URL, or invalid cookies. Essentially, the server cannot understand the request, leading to this error.

So, you’ve encountered the dreaded “400 Bad Request Nginx” error and are unsure how to proceed. Don’t fret! We’re here with a comprehensive fixing guide to help you navigate through these turbulent tech waters.

First, let’s dive into one common scenario that might ring a bell – 400 bad request nginx the plain HTTP request was sent to HTTPS port. This typically arises when a non-encrypted request (HTTP) is sent to an encrypted port (HTTPS). It’s like attempting to fit a square peg in a round hole – it just won’t work! So, correcting the port in your URL is a solid starting point.Causes of 400 Bad Request Nginx

Next, let’s talk about the 400 bad request rest API issue. This often happens when there’s something amiss with the data you’re trying to send through the API.

For example, you may have sent incorrect parameters or headers, or the syntax of the request body is off. It’s important to verify the information you’re sending to ensure everything’s in tip-top shape.

Have you ever seen the HTTP proxy status 400 “400 bad request” error? This usually indicates a problem with the proxy server between the client and the server. On the other hand, it might appear due to a wrong configuration or an issue with the server itself. Resetting or reconfiguring your proxy settings could work wonders here.

Lastly, we have the client sent invalid method while reading client request line situation. This happens when the HTTP method sent by the client is unrecognized or unsupported by the server. Ensuring you’re using a valid method like GET, POST, PUT, DELETE, etc., could quickly resolve this problem.

So, there you have it! Each scenario can give you a headache, but with some know-how and this guide in your arsenal, you’ll be well-equipped to tackle the 400 Bad Request Nginx errors head-on.

– Non-Encrypted Request Is Sent To An Encrypted Port

We’ve all been there. You’re trying to access a site but have an error message. One common cause is when a non-encrypted request (HTTP) is sent to an encrypted port (HTTPS). This might seem like a mess of techno-jargon, but it’s like trying to fit a square peg in a round hole.

Take a look at this example:

“`html

http://www.yoursite.com:/443

“`

The URL requests an HTTP to port 443, a standard HTTPS port. This will invariably trigger the error.

In addition, you could remove the flawed symbol, which will not remove the bug, as shown here:

“`html

https://www.yoursite.com: 443

“`

The request is encrypted correctly, but the code exception persists and ruins your program.

– Amiss With The Data You Are Sending

Sending a request to an API is like posting a letter: the envelope (headers), address (URL), and content (body) all have to be perfect. If there’s something amiss with any of these elements, you’ll encounter the dreaded 400 bad request error.Amiss With The Data

For instance, you might be sending a JSON request body like:

“`javascript

{

name: “John Doe”

age: “25”

}

“`

Missing a comma, the server gets confused and returns an error.

Still, here’s another example of a broken code snippet:

“`javascript

{

“name”: “John Doe”,

“age”: “25”,

}

“`

The server can easily parse the first element but confuses the second input with an extra coma.

– Proxy Server Issues Between The Client and Server

Sometimes, the issue isn’t with your request or the server but with the middleman – the proxy server. A proxy setup is an intermediary between your client and the server you’re trying to reach.

Let’s imagine you’re trying to access a site, but you get an “HTTP proxy status 400 “400 bad request” error. This usually signals a misconfiguration on the proxy.

However, fixing this isn’t as simple as modifying some code. First, you’ll need to delve into your network settings and rectify the proxy settings, which might involve talking to your network administrator.

Remember, the internet is like a series of conversations. So ensuring clear, correct dialogue is key to avoiding those frustrating 400 errors.

How to Fix the 400 Bad Request Nginx Code Exception?

Fixing the “400 Bad Request Nginx” error involves identifying the root cause. For example, it could be a malformed HTTP request, an incorrect URL, or invalid cookies. You can resolve this issue by adjusting your request, correcting the URL, or clearing your cookies.

We’ve all had those forehead-slapping moments when the “400 Bad Request Nginx” error pops up on our screens. It’s frustrating, right? But don’t worry because we’ve got your back. Let’s walk through a few scenarios to help you troubleshoot this pesky issue.

Firstly, the error may result from malformed syntax in your HTTP request. It’s like typing gibberish and expecting a coherent response – it won’t work. In this scenario, check the syntax of your request carefully. Look out for any typos or format errors and correct them. This might seem apparent, but you’d be surprised how often a simple typo can cause headaches.

Now, let’s consider another common scenario – you’ve got the right syntax, but the URL in your request is incorrect. It’s like dialing the wrong number and wondering why your friend isn’t picking up. Double-check the URL you’re using, and ensure it’s correct for the server you’re trying to reach.

Lastly, here’s a scenario that often flies under the radar – invalid cookies. These are like expired tickets – they won’t get you where you need to go. If your browser has stored no longer valid cookies, this could cause the 400 error. In this case, try clearing your browser’s cookies and cache. This is a simple fix, but it can often do the trick.Solutions for 400 Bad Request Nginx

– Check The Syntax of Your Request

When sending an HTTP request, ensuring your syntax is flawless is crucial. Any typos or format errors can lead to that dreaded 400 Bad Request Nginx error. It’s like attempting to write a letter with jumbled words – it won’t make sense to the recipient!

Here’s an example of a well-structured GET request in a command line tool like curl:

“`bash

curl -X GET http://example.com

“`

In this request, `-X` specifies the method (in this case, GET), and the URL follows. Ensuring all elements are in their right place and spelled correctly is essential for your request to go through smoothly.

– Ensure You Use The Correct URL

Using the correct URL is like dialing a valid phone number – it’s how you reach the right destination. Conversely, an incorrect URL is a common cause of the 400 error. Therefore, it’s critical to double-check your URL for any typos or outdated information.

Suppose you’re trying to reach `http://example.com/api/users`. If you mistype it as `http://example.com/api/usres`, you’ll get a 400 error because the server can’t find the `usres` endpoint.

– Clear Your Browser’s Cookies And Cache

Your browser’s cookies and cache can be compared to little memory snippets. However, sometimes these snippets get outdated or corrupted, leading to errors like the 400 Bad Request.Clearing Browser s Cookies And Cache

Here’s a simple guide to clearing your cache and cookies in Google Chrome:

  1. Click on the three-dot icon in the top right section.
  2. Select “More tools” and then locate “Clear browsing data”.
  3. Opt for “Cookies and other site data” and “Cached image and file”.
  4. Click “Clear data”.

Remember, each browser has steps for clearing cache and cookies, so using Firefox, Safari, or Edge might be different.

Correct syntax, the right URL, and a clean cache are your allies in battling the 400 Bad Request Nginx error. With these inputs at your disposal, you can resolve these issues efficiently.

Fixing the 400 Bad Request Nginx error can sometimes feel like a game of detective. But you can successfully navigate these tech waters with a little persistence and the right approach. Remember, it’s all about understanding the cause of the error and applying the right solution.

Conclusion

Solving the “400 Bad Request Nginx” error might seem scary at first, but it can be overcome with a bit of patience. Here’s a quick summary of what we’ve covered:

  • Malformed client requests, including issues with HTTP headers or server configurations, typically cause 400 Bad Request Nginx errors.
  • Different types of these errors exist, such as ‘nginx 400 157’ or ‘400 bad request rest API’, each having its unique trigger.
  • Effective troubleshooting requires diagnosing the cause, often involving server logs, HTTP headers, and potentially code revisions.
  • Preventive measures can greatly reduce the likelihood of encountering these errors in the future.

Remember, every tech issue is an opportunity for learning and growth. So, the next time you encounter a “400 Bad Request Nginx” error, take it as a challenge to dig deeper, understand the cause, and fix it like a pro.

  • Author
  • Recent Posts

Position is Everything

Your Go-To Resource for Learn & Build: CSS,JavaScript,HTML,PHP,C++ and MYSQL. Meet The Team

Position is Everything

Понравилась статья? Поделить с друзьями:

Интересное по теме:

  • Ошибка 3f62 bmw
  • Ошибка 400 bad request chat not found
  • Ошибка 3f57 bmw m57
  • Ошибка 400 рекстон
  • Ошибка 400 autocad

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии