I get an "400 Bad Request" error when I call my API with private integration in Amazon API Gateway.
Resolution
"400 Bad Request" errors occur when there are configuration errors in HTTP and REST API requests.
HTTP APIs
An Application Load Balancer or a Network Load Balancer with a listener that's configured on an HTTPS or TLS port receives a request
By default, private integrations for HTTP APIs use the HTTP protocol. However, if you have an HTTPS or TLS listener configured, the load balancer expects HTTPS requests instead. This results in the following error:
<html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
<hr><center>nginx</center>
</body>
</html>
For an HTTPS or TLS listener, you must specify a server name in the TLS configuration. To configure the HTTPS protocol, complete the following steps:
- Record the domain name of the internal Application Load Balancer or Network Load Balancer.
- Sign in to the API Gateway console.
- Open the API's integration settings to edit the configuration.
- Use the domain name from step 1 to specify the server name for the TLS configuration.
Note: For more information, see the integration's TLS configuration.
Desync migration mode is set to strictest
HTTP APIs allow for private integration or virtual private cloud (VPC) link integration using an Application Load Balancer. If your Application Load Balancer's desync mitigation mode is set to strictest when your API Gateway is correctly configured, then you receive the following error:
<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
</body>
</html>
Desync mitigation mode protects your application from issues caused by HTTP desync. For more information, see the mode information in your Application Load Balancer access logs, or check the DesyncMitigationMode_NonCompliant_Request_Count Amazon CloudWatch metric.
To turn off desync mitigation mode, complete the following steps:
- Sign in to the Amazon Elastic Compute Cloud (Amazon EC2) console.
- In the navigation pane, choose Load Balancers, and then select the Network Load Balancer you want to edit.
- Change the Application Load Balancer's packet handling to defensive mode.
REST API
A Network Load Balancer with a listener that's configured on a TLS port receives a request
When a Network Load Balancer is configured with a TLS listener, the load balancer expects HTTPS requests from the upstream service. Within the REST API configuration, if you mention HTTP URL as an integration endpoint URL, the request is rejected with the following response:
<html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
<hr><center>nginx</center>
</body>
</html>
To configure the HTTPS protocol, complete the following steps:
- Sign in to the API Gateway console.
- Open the API's integration settings to edit the configuration.
- Modify the endpoint URL to use https:// instead of http://.
- Redeploy the API.
Important: When endpoint URL changes apply to HTTPS, remember to use the corresponding domain name that you used when you configured the TLS listener.
Related information
Access logs for your Application Load Balancer