highIntermediateSymptom-first#services#loadbalancer#cloud#ingress

Service LoadBalancer stuck Pending — no external IP

kubectl get svc shows <pending> for EXTERNAL-IP

Likely source:availabilitynetworking

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 -20
  • Load 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'
READ

Look for the controller

Fix

helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=<cluster>
CHANGE

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.

1
kubectl get svc -A | grep pending
READ

Find all stuck LoadBalancers

2
kubectl describe svc <svc> -n <namespace> | tail -30
READ

Read the event for the reason

3
kubectl get pods -A | grep -E 'aws-load-balancer|cloud-controller'
READ

Verify the controller runs

4
kubectl logs -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller --tail=100
READ

Read 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.

Commands marked READ CHANGE DESTRUCTIVE — never run DESTRUCTIVE commands against production data you cannot restore. Copy → verify → execute.