Service LoadBalancer stuck Pending — no external IP
kubectl get svc shows <pending> for EXTERNAL-IP
Focused incident mode — strips away everything but this runbook.
Symptoms
- kubectl get svc shows <pending> for EXTERNAL-IP
- Site unreachable from the internet
- No LoadBalancer object appears in the cloud console
Evidence to grab
Collect these artifacts before you change anything — they prove (or rule out) each cause.
Service event log
kubectl describe svc <svc> -n <namespace> | tail -20Load balancer controller pods
kubectl get pods -A | grep -E 'aws-load-balancer|cloud-controller'
Diagnostic flow
Run the steps in order, marking each claim confirmed or refuted. The evidence you gather feeds the ranked causes below.
Guided decision tree is ready.
Steps with commands, expected output, and pass/fail branches.
Ranked root causes
Evidence checklist
- No events for the Service at all
- No aws-load-balancer-controller or cloud-controller-manager pods
Confirm before fixing
kubectl get pods -A | grep -E 'aws-load-balancer|cloud-controller'Look for the controller
Fix
helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=<cluster>Install the in-cluster LB controller (EKS example)
Expected: aws-load-balancer-controller installed
Resolution runbook
Apply from top to bottom after the cause is confirmed. Review every command before running it — risk tags are shown on each.
kubectl get svc -A | grep pendingFind all stuck LoadBalancers
kubectl describe svc <svc> -n <namespace> | tail -30Read the event for the reason
kubectl get pods -A | grep -E 'aws-load-balancer|cloud-controller'Verify the controller runs
kubectl logs -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller --tail=100Read controller errors and fix per annotation
Prevention
- Install the LB/CCM controller in the cluster bootstrap step.
- Pin subnets via annotations and keep them in the cluster role policy.
- Use Ingress with a shared ingress controller instead of per-service LBs where possible.
Related runbooks
Same stack, same failure family — worth a skim.
Commands marked READ CHANGE DESTRUCTIVE — never run DESTRUCTIVE commands against production data you cannot restore. Copy → verify → execute.