Resolution
To troubleshoot failed health checks for your Application Load Balancer, you can run the AWSSupport-TroubleshootELBHealthChecks runbook. The runbook automates the analysis of health check metrics from your Amazon CloudWatch dashboard. The runbook also validates network configurations across Application Load Balancer and your targets. For targets managed by AWS Systems Manager, the runbook provides advanced diagnostic commands with optional log retention in Amazon S3. The runbook solution applies to the instance target type.
You can also use the Application Load Balancer resource map to view the load balancer's resources and identify unhealthy targets. The resource map shows all Application Load Balancer resources on a single page.
Note: If the target HTTP response of the Application Load Balancer isn't the expected response, then check your application's response. Make sure that the application sends the correct response to the load balancer.
Based on the health check reason code that you find, take the following troubleshooting actions.
Elb.InitialHealthChecking
Before a target can receive requests from the load balancer, the target must pass initial health checks. Wait for your target to pass the initial health checks, and then recheck its health status.
Elb.RegistrationInProgress
Target registration is in progress. Wait for the registration to complete and for the target to pass initial health checks. The load balancer automatically routes requests to the target after it registers the target.
Target.DeregistrationInProgress
The target group removes the target. The load balancer stops new requests to the target as it completes in-flight requests. The default deregistration delay lasts 300 seconds. To check or modify the delay value, see Deregistration delay.
Target.FailedHealthChecks
Launch or use an available Amazon Elastic Compute Cloud (Amazon EC2) instance in the same virtual private cloud (VPC) as the target instance. Make sure that you have access to this instance. For publicly accessible targets, run the following command to send a health check request directly to the target instance's public IP address:
curl -vkso /dev/null HealthCheck_protocol://Target_IP:HealthCheck_port/HealthCheck_path
Note: Replace Target_IP with the target instance's IP address, HealthCheck_port with the health check port, and HealthCheck_path with the health check path. The preceding command bypasses the load balancer to test the target's response
To verify how your application responds to the load balancer's health check requests, run the following command to simulate a health check request:
curl -H "User-Agent: ELB-HealthChecker/2.0" -I http://localhost:PORT/HEALTH_CHECK_PATH
Note: Replace PORT with your application's port number and HEALTH_CHECK_PATH with your health check path.
Verify the response includes an HTTP status code that matches your configured success code. The default success code is 200. If you can't use curl, then check your application's logs for requests from the ELB-HealthChecker/2.0 user-agent.
The following example is a typical health check request from the Application Load Balancer with a valid HTTP response:
GET / HTTP/1.1
Host: 10.0.0.1:80
Connection: close
User-Agent: ELB-HealthChecker/2.0
Accept-Encoding: gzip, compressed
Note: In the preceding example, the Host header value contains the private IP address of the target, followed by the health check port. The User-agent is set to ELB-HealthChecker/2.0. If your application doesn't receive the health check requests, then add a default virtual host entry that matches the health check port.
If you attached multiple elastic network interfaces to your target, then confirm that your application is listening on the correct network interface. To check the interface that your application uses, run the following command:
netstat -an | grep LISTEN
Verify that your application's port uses the correct interface IP address. For more information about how network interfaces work with different target types and how to correctly configure them, see Target type.
Confirm that the target provides a server certificate and a key in the format that you specified in the Elastic Load Balancing security policy. Check whether the target supports the matching ciphers and the protocol that the load balancer provides to establish the SSL/TLS handshake.
To verify SSL/TLS cipher support, run the following command on your target:
openssl s_client -connect your_target:443 -servername your_target
Note: Replace your_target with your target.
Compare the supported ciphers in the output with the ciphers listed in your load balancer's security policy.
Linux targets
For Linux targets, run the following command to check if your service is active and running:
service httpd status
Note: Replace httpd with the service name.
Look for active in the output.
Example output:
Redirecting to /bin/systemctl status httpd.service
httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; preset: disabled)
Active: active (running) since Fri 2025-06-13 07:00:35 UTC; 16s ago ------------------------------------------------> server status
Docs: man:httpd.service(8)
Main PID: 10146 (httpd)
Status: "Total requests: 0; Idle/Busy workers 100/0;Requests/sec: 0; Bytes served/sec: 0 B/sec"
Tasks: 177 (limit: 9486)
Memory: 17.9M
CPU: 90ms
CGroup: /system.slice/httpd.service
├─10146 /usr/sbin/httpd -DFOREGROUND
├─10147 /usr/sbin/httpd -DFOREGROUND
├─10148 /usr/sbin/httpd -DFOREGROUND
├─10149 /usr/sbin/httpd -DFOREGROUND
└─10150 /usr/sbin/httpd -DFOREGROUND
Jun 13 07:00:35 ip-172-16-1-59.ec2.internal systemd[1]: Starting httpd.service - The Apache HTTP Server...
Jun 13 07:00:35 ip-172-16-1-59.ec2.internal systemd[1]: Started httpd.service - The Apache HTTP Server.
Jun 13 07:00:35 ip-172-16-1-59.ec2.internal httpd[10146]: Server configured, listening on: port 80 ---------------->listening port
If the service shows as inactive or failed, then run the following command to start the service:
service httpd start
Note: Replace httpd with the service name.
To confirm that Linux targets are listening for traffic on the health check port, run the following command:
ss -nral | grep PORT_NUMBER
Note: Replace PORT_NUMBER with your health check port. For example, use 80 for HTTP.
Example output:
tcp LISTEN 0 511 * :80 * :*
Windows targets
For Windows targets, check the Services tab of Windows Task Manager. If the service is stopped, then start the service. If Windows doesn't recognize the service, then check whether you installed the service.
To verify that the Windows targets are listening for traffic on the health check port, run the following command:
netstat -an | findstr LISTEN | findstr :PORT_NUMBER
Note: Replace PORT_NUMBER with your health check port.
Target.InvalidState
If the target is an Amazon EC2 instance, then use the Amazon EC2 console to verify that the instance is running. If the instance isn't running, then manually start the instance. If the target isn't an EC2 instance, then check the status of your target in the AWS Management Console for the service.
Target.IpUnusable
If your target type is ip, then don't choose an IP address that a load balancer already uses. To update your IP address, complete the following steps:
- Open the Amazon EC2 console.
- In the navigation pane, choose Instances.
- Choose Action, and then select Networking.
- Choose Manage IP addresses.
- Modify the primary private IP address.
- Choose Save.
- Reboot the instance.
Target.NotInUse
To check whether you configured the target group to receive traffic from the load balancer, complete the following steps:
- Open the Amazon EC2 console.
- In the navigation pane, choose Load balancers.
- Select your load balancer.
- Choose Action, and then select Manage listeners.
- Confirm that you associated your target group with at least one active listener.
To update an Availability Zone for your load balancer, see Update the Availability Zones for your Application Load Balancer.
Target.NotRegistered
Make sure that you registered the target to the target group.
Target.ResponseCodeMismatch
To verify success codes, review your health check configuration to identify the success codes that your load balancer expects. Then, open your web server access logs and check the HTTP status codes that your application returns to the load balancer. Make sure that the codes match the configured success codes. The default success code is 200, but you can configure a custom success code in the 200-499 range.
Also, confirm that your ping path exists and uses a valid URI. The default is /.
If the codes don't match or the ping path is invalid, then update your application or health check settings with the correct information.
Target.Timeout
If you can connect, then the target page might not respond before the health check timeout period. For web servers such as NGINX and Internet Information Services (IIS), you can log how long the server takes to respond. For more information, see Configuring logging on the NGINX website and Configure logging in IIS on the Microsoft website.
If your health check requests take longer than the configured timeout, then use a target page that contains minimal dynamic content. To modify your health check path, see Update the health check settings of an Application Load Balancer target group.
If you can't connect, then take the following actions:
- Use the health check port and health check protocol to verify that the target instance's security group allows traffic from the load balancer. You can add a rule to the security group to allow all traffic from the load balancer security group.
- Make sure that the security group for your Application Load Balancer allows traffic to the target instance.
- Verify that the target instance's network access control list (network ACL) allows inbound traffic on the health check port and outbound traffic on the ephemeral ports (1024-65535).
- Verify that the node subnet's network ACL allows inbound traffic on the ephemeral ports and outbound traffic on the health check and ephemeral ports.
- Check whether the operating system (OS) firewalls on the target allow health check traffic in and out.
- Verify that the route table for the target's subnets contains an entry that allows health check traffic back to the load balancer.
- Check your target's memory and CPU usage. If the memory or CPU usage is too high, then add targets or increase the capacity of your Amazon EC2 Auto Scaling group. If your target is an Amazon EC2 instance, then change the instance to a larger instance type.
Related information
Troubleshoot your Application Load Balancers