LB-HEALTH-CHECK-TIMEOUT

Cloud LB Backend Registration Fails on Health Check

Server & Cloud Intermediate 👁 5 views 📅 Jun 23, 2026

When a VM fails the load balancer's health check, the backend won't register. This usually means the app or firewall isn't ready. Here's how to fix it.

So you set up a cloud load balancer — Azure, AWS, GCP, doesn't matter. You add your VM to the backend pool, and it stays unhealthy or unavailable. The load balancer won't send traffic to it. I've seen this error pop up right after you deploy a fresh VM and attach it to the load balancer. The trigger is almost always the health check probe failing.

Root cause in plain English

The load balancer sends a tiny health check request — usually a TCP ping or an HTTP GET — to your VM's IP and port (like port 80 for web apps). If the VM doesn't respond within a few seconds (maybe 5–30 seconds depending on your config), the load balancer marks it as unhealthy. The backend never registers. The most common reasons:

  • The application on the VM isn't running yet or crashed.
  • A firewall (like iptables, Windows Firewall, or a network security group) blocks the health check traffic.
  • The health check path or port is wrong — like you set it to /health but your app only answers on /index.html.

Fix it — step by step

Step 1: Check the VM's application status

SSH or RDP into the VM. Make sure your web server or app is running. For a simple test:

# On Linux
systemctl status nginx
# Or check process
ps aux | grep nginx

# On Windows
Get-Service -Name W3SVC  # IIS

If it's not running, start it. Also check the app's port is listening:

# Linux
netstat -tulnp | grep :80
# Windows
netstat -an | findstr :80

Step 2: Verify the health check path and port

Open the load balancer settings. For HTTP health checks, the probe sends a GET request to a specific path (like / or /health). Your app must return a 200 OK on that exact path. Test it from inside the VM:

curl -v http://localhost/health
# Should return HTTP/1.1 200 OK

If it returns a 404 or 500, fix your app's route. Or change the health check path to something that works, like /index.html.

Step 3: Check firewalls — the real gotcha

This tripped me up the first time too. Cloud load balancers often send health checks from a specific IP range or subnet. For example, Azure health probes come from the Azure Load Balancer's IP (168.63.129.16). AWS uses the VPC subnet's IP range. GCP uses the health check IP ranges (35.191.0.0/16 and 130.211.0.0/16).

If your VM's firewall (like Windows Firewall or iptables) blocks these IPs, the health check fails. Also check cloud firewalls — network security groups (NSG) in Azure, security groups in AWS, firewall rules in GCP.

Example: In Azure, you must allow inbound traffic from AzureLoadBalancer service tag. In AWS, allow the VPC CIDR range. In GCP, allow the health check ranges.

Step 4: Test the health check from outside the VM

If you can access the VM from another machine (like a jump box), try sending a request to the VM's IP on the health check port:

# From another machine in the same network
curl -v http://192.168.1.10/health

If that fails, the issue is definitely the firewall or the app on the VM. If it works, double-check the load balancer's probe configuration — maybe the probe port is different from the app port.

Still failing? Check these

  • Probe interval vs. unhealthy threshold: Defaults usually work, but if your app takes longer than the probe interval to respond (like a slow startup), increase the interval or set a higher unhealthy threshold (like 5 failures before marking unhealthy).
  • Backend pool membership: Make sure the VM is actually in the backend pool. Sounds silly, but I've seen people attach the VM to the wrong pool.
  • Multiple network interfaces: If the VM has multiple NICs, the load balancer might probe the wrong one. Only primary NIC is supported for most clouds.
  • Route tables: Make sure there's no custom route that sends traffic away from the VM.

If you've done all this and it still won't register, try restarting the load balancer's backend pool (re-add the VM) or restart the VM. Sometimes the probe state gets stuck — it happens.

Was this solution helpful?