Backend Server Fails Registration in AWS ALB – 3 Fixes
Your EC2 instance won't register with the ALB target group. Usually it's a security group rule, a health check path mismatch, or the instance is in a bad state. Here's the fix order to check first.
1. Security Group Blocks Health Check Traffic
This is the #1 reason your backend server fails registration. The ALB sends health check requests from its own IP range, not from your VPC subnet. If your EC2 instance's security group doesn't explicitly allow traffic from the ALB's subnets, the health check times out, and the target group shows unhealthy.
Real trigger: You launch a new instance, copy the security group from an old one, but forget that the old group had a rule like sg-12345 (the ALB's security group) allowed on port 80. Or you moved the ALB to a different VPC without updating the security group.
Fix
- Go to EC2 → Security Groups → select the security group attached to your backend instances.
- On the Inbound rules tab, click Edit inbound rules.
- Add a rule:
Type: Custom TCP Port: 80 (or your app's port) Source: Custom → paste the ALB's security group ID (looks like sg-xxxxxxxx) - Save. Then wait 10 seconds and check the target group health status again.
What's actually happening here is the ALB's health check requests come from its ENIs (Elastic Network Interfaces), which are associated with the ALB's security group. If that group isn't allowed inbound to your backend, the packets get dropped. The instance never sees the request, so it never responds.
I've seen people spend hours debugging application misconfigurations when the real issue was this one rule missing. Always check security groups first.
2. Health Check Path or Protocol Mismatch
Second most common cause. Your target group expects the backend to respond on a specific path, but your app doesn't serve that path, or serves it with a different HTTP status code.
For example, default health check path is /. Your app might be a Node.js server that only responds on /api/health with a 200. The ALB hits /, gets a 404, marks the instance unhealthy. Another common one: you set health check to use HTTP but your app only accepts HTTPS.
Fix
- Go to EC2 → Target Groups → select your target group → Health checks tab.
- Note the Path and Protocol.
- SSH into the backend instance and test the same path with curl:
If you get anything other than a 200, that's your problem. If you get a 502 or connection refused, the app isn't listening on that port.curl -I http://localhost:80/ - Adjust the health check path in the target group to match your app's actual health endpoint. Or fix the app to serve the expected path.
The reason step 3 works is curl bypasses the ALB's security group and hits the instance directly. So you isolate the health check issue from the network issue. If curl returns 200 but the ALB still reports unhealthy, go back to fix #1 — it's a security group thing.
3. Instance in a Bad State or Not Serving Traffic
This sounds obvious but people miss it. The instance might be running but its web server crashed, or it's in the middle of an OS update, or the disk is full and the app can't write logs. The ALB sees no response, marks it unhealthy.
Fix
- Check the instance status in EC2 console. Look for Status checks — both system and instance checks should pass.
- SSH into the instance and run:
sudo systemctl status nginx # or httpd, or your app's service name journalctl -u nginx --no-pager | tail -20 - Check disk space:
If it's 100%, the app can't write anything. Free up space or increase the volume.df -h - Check the app's log file for errors. For example, a Node.js app might show
EADDRINUSEif two instances tried to bind the same port. - Restart the app service and check if it binds to the expected port with
ss -tulpn | grep :80.
I ran into this once on a t2.micro instance that ran out of memory. The app process was killed by the OOM killer. The instance looked fine from the EC2 console, but the app was dead. A simple sudo systemctl restart myapp fixed it.
Quick-Reference Summary
| Cause | Symptom | Fix | Check First |
|---|---|---|---|
| Security group blocks health checks | Instance shows unhealthy, curl from instance works |
Add inbound rule from ALB's security group | EC2 → Security Groups → Inbound rules |
| Health check path mismatch | Instance shows unhealthy, curl returns non-200 |
Update health check path or fix app endpoint | Target Group → Health checks tab |
| Instance not serving traffic | Instance status checks pass, but app is down | Restart app, free disk, fix log errors | SSH into instance and check service status |
Follow this order — security group first, health check second, instance state third — and you'll fix 95% of backend registration failures in under 10 minutes.
Was this solution helpful?