I ran into this issue (unexpected HTTP 400 status codes) and here's what I learned. My symptoms were as follows:
Load balancer requests to /health returned HTTP 400
Requests to /health from the host itself also returned HTTP 400 (e.g.: wget http://localhost/health).
Requests to /health from the internet worked.
The underlying problem was with $settings['trusted_host_patterns'] in settings.php. Both localhost and the host name the load balancers were using to request /health were not in $settings['trusted_host_patterns'].
My webhosts are on AWS, so adding these values to $settings['trusted_host_patterns'] made things work:
// To allow wget and curl to work on individual webhosts.
'^localhost$',
// AWS EC2 internal IP-based host patterns to allow /health to work as the ELB ping route.
'^ip-' . str_replace('.', '-', gethostbyname(gethostname())) . '\\.ec2\\.internal$',
'^.+\\.ip-' . str_replace('.', '-', gethostbyname(gethostname())) . '\\.ec2\\.internal$',
'^' . str_replace('.', '\\.', gethostbyname(gethostname())) . '$',
'^+\\.' . str_replace('.', '\\.', gethostbyname(gethostname())) . '$',
The specific patterns above might not work for your situation, but for those experiencing unexpected HTTP 400s when /health is requested one possible solution is to figure out the hostname being used to when those problematic requests to /health are being made and getting those into $settings['trusted_host_patterns'].