# Debug 400 error?

**URL:** <https://discourse.haproxy.org/t/debug-400-error/8985>\
**Category:** Help!\
**Created:** [August 31, 2023, 9:33am UTC](https://discourse.haproxy.org/t/debug-400-error/8985 "2023-08-31T09:33:43Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![frefal](https://avatars.discourse-cdn.com/v4/letter/f/71e660/32.png) [@frefal](https://discourse.haproxy.org/u/frefal)\
**Post date:** [August 31, 2023, 9:33am UTC](https://discourse.haproxy.org/t/debug-400-error/8985/1 "2023-08-31T09:33:43Z")

</div>

I have a case where some requests gets return a 400 error from haproxy, others not. The requests themselves look very similar.

I would like to find out what is the reason for the 400 error. Can you please suggest the best way to do this?

What I have tried so far is the following:

1. 

This command suggested by others, outputs 0 events.

echo “show errors” | socat stdio unix-connect:/run/haproxy/admin.sock  
Total events captured on [31/Aug/2023:11:29:22.602] : 0

The config contains: stats socket /run/haproxy/admin.sock mode 600 level admin

1. 

I have tried to increase the logging level. But the change here does not increase the amount of detail in the log file.

log /dev/log local0 info  
log /dev/log local1 debug

frontend and backend are using log global

Many thanks 🙂

HAProxy version 2.8.1-1~bpo11+1 2023/07/03 - [https://haproxy.org/](https://haproxy.org/)  
Status: long-term supported branch - will stop receiving fixes around Q2 2028.  
Known bugs: [http://www.haproxy.org/bugs/bugs-2.8.1.html](http://www.haproxy.org/bugs/bugs-2.8.1.html)  
Running on: Linux 5.10.0-19-amd64 #1 SMP Debian 5.10.149-2 (2022-10-21) x86\_64  
Build options :  
TARGET = linux-glibc  
CPU = generic  
CC = cc  
CFLAGS = -O2 -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D\_FORTIFY\_SOURCE=2 -Wall -Wextra -Wundef -Wdeclaration-after-statement -Wfatal-errors -Wtype-limits -Wshift-negative-value -Wshift-overflow=2 -Wduplicated-cond -Wnull-dereference -fwrapv -Wno-address-of-packed-member -Wno-unused-label -Wno-sign-compare -Wno-unused-parameter -Wno-clobbered -Wno-missing-field-initializers -Wno-cast-function-type -Wno-string-plus-int -Wno-atomic-alignment  
OPTIONS = USE\_OPENSSL=1 USE\_LUA=1 USE\_SLZ=1 USE\_SYSTEMD=1 USE\_PROMEX=1 USE\_PCRE2=1 USE\_PCRE2\_JIT=1  
DEBUG = -DDEBUG\_STRICT -DDEBUG\_MEMORY\_POOLS

Feature list : -51DEGREES +ACCEPT4 +BACKTRACE -CLOSEFROM +CPU\_AFFINITY +CRYPT\_H -DEVICEATLAS +DL -ENGINE +EPOLL -EVPORTS +GETADDRINFO -KQUEUE -LIBATOMIC +LIBCRYPT +LINUX\_SPLICE +LINUX\_TPROXY +LUA +MATH -MEMORY\_PROFILING +NETFILTER +NS -OBSOLETE\_LINKER +OPENSSL -OPENSSL\_WOLFSSL -OT -PCRE +PCRE2 +PCRE2\_JIT -PCRE\_JIT +POLL +PRCTL -PROCCTL +PROMEX -PTHREAD\_EMULATION -QUIC +RT +SHM\_OPEN +SLZ +SSL -STATIC\_PCRE -STATIC\_PCRE2 +SYSTEMD +TFO +THREAD +THREAD\_DUMP +TPROXY -WURFL -ZLIB

Default settings :  
bufsize = 16384, maxrewrite = 1024, maxpollevents = 200

Built with multi-threading support (MAX\_TGROUPS=16, MAX\_THREADS=256, default=4).  
Built with OpenSSL version : OpenSSL 1.1.1n 15 Mar 2022  
Running on OpenSSL version : OpenSSL 1.1.1n 15 Mar 2022  
OpenSSL library supports TLS extensions : yes  
OpenSSL library supports SNI : yes  
OpenSSL library supports : TLSv1.0 TLSv1.1 TLSv1.2 TLSv1.3  
Built with Lua version : Lua 5.3.3  
Built with the Prometheus exporter as a service  
Built with network namespace support.  
Built with libslz for stateless compression.  
Compression algorithms supported : identity(“identity”), deflate(“deflate”), raw-deflate(“deflate”), gzip(“gzip”)  
Built with transparent proxy support using: IP\_TRANSPARENT IPV6\_TRANSPARENT IP\_FREEBIND  
Built with PCRE2 version : 10.36 2020-12-04  
PCRE2 library supports JIT : yes  
Encrypted password support via crypt(3): yes  
Built with gcc compiler version 10.2.1 20210110

Available polling systems :  
epoll : pref=300, test result OK  
poll : pref=200, test result OK  
select : pref=150, test result OK  
Total: 3 (3 usable), will use epoll.

Available multiplexer protocols :  
(protocols marked as cannot be specified using ‘proto’ keyword)  
h2 : mode=HTTP side=FE|BE mux=H2 flags=HTX|HOL\_RISK|NO\_UPG  
fcgi : mode=HTTP side=BE mux=FCGI flags=HTX|HOL\_RISK|NO\_UPG  
 : mode=HTTP side=FE|BE mux=H1 flags=HTX  
h1 : mode=HTTP side=FE|BE mux=H1 flags=HTX|NO\_UPG  
 : mode=TCP side=FE|BE mux=PASS flags=  
none : mode=TCP side=FE|BE mux=PASS flags=NO\_UPG

Available services : prometheus-exporter  
Available filters :  
[BWLIM] bwlim-in  
[BWLIM] bwlim-out  
[CACHE] cache  
[COMP] compression  
[FCGI] fcgi-app  
[TRACE] trace

---

<div class="post-metadata">

**Author:** ![lukastribus](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@lukastribus](https://discourse.haproxy.org/u/lukastribus)\
**Post date:** [August 31, 2023, 11:30am UTC](https://discourse.haproxy.org/t/debug-400-error/8985/2 "2023-08-31T11:30:34Z")

</div>

You need to enable **[option httplog](http://docs.haproxy.org/2.6/configuration.html#4.2-option%20httplog)**.

---

<div class="post-metadata">

**Author:** ![frefal](https://avatars.discourse-cdn.com/v4/letter/f/71e660/32.png) [@frefal](https://discourse.haproxy.org/u/frefal)\
**Post date:** [August 31, 2023, 11:42am UTC](https://discourse.haproxy.org/t/debug-400-error/8985/3 "2023-08-31T11:42:27Z")

</div>

Thanks! This one is already enabled under both defaults and frontend. And frontend is using mode http.

---

<div class="post-metadata">

**Author:** ![lukastribus](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@lukastribus](https://discourse.haproxy.org/u/lukastribus)\
**Post date:** [August 31, 2023, 11:54am UTC](https://discourse.haproxy.org/t/debug-400-error/8985/4 "2023-08-31T11:54:52Z")

</div>

Ok, then share the log outputs and the configuration.

---

<div class="post-metadata">

**Author:** ![lukastribus](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@lukastribus](https://discourse.haproxy.org/u/lukastribus)\
**Post date:** [August 31, 2023, 1:13pm UTC](https://discourse.haproxy.org/t/debug-400-error/8985/6 "2023-08-31T13:13:35Z")

</div>

The log indicates that the 400 error comes from your backend server and that 169 bytes have been transmitted to the client from the `bkend3` server.

Usually if harpoxy rejects a request a backend server is not assigned (and you see the reason in logs and on the admin console).

Does the 400 error contain a haproxy typical 400 error or what does the response header and payload on the client actually look like?

---

<div class="post-metadata">

**Author:** ![frefal](https://avatars.discourse-cdn.com/v4/letter/f/71e660/32.png) [@frefal](https://discourse.haproxy.org/u/frefal)\
**Post date:** [August 31, 2023, 1:26pm UTC](https://discourse.haproxy.org/t/debug-400-error/8985/7 "2023-08-31T13:26:40Z")

</div>

Thanks. In the client application, I just see HTTP/1.1 400. Its not a web page so it makes it a bit harder to debug. Is there a way to catch more details about the response from the backend in this case?

---

<div class="post-metadata">

**Author:** ![lukastribus](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@lukastribus](https://discourse.haproxy.org/u/lukastribus)\
**Post date:** [August 31, 2023, 3:12pm UTC](https://discourse.haproxy.org/t/debug-400-error/8985/8 "2023-08-31T15:12:28Z")

</div>

Well if the backend server returns 400 bad request really this should be debugged on the backend server.

If you want to capture the traffic between haproxy and the backend, the easiest is usually to downgrade from ssl to plaintext (just on the backend), so you can analyse it.

Otherwise considering its ssl encrypted you’d have to track encryption keys, or use the private key of the cert along with a non-FS cipher to decrypt the traffic.
