How to fix load balancer pending ip in Kubernetes

KubernetesINTERMEDIATEMEDIUMUpdated Dec 6, 2025ยท 217 views

LoadBalancer services stuck in "pending" state cannot assign external IPs. This blocks external traffic and prevents service exposure. Usually caused by cloud provider delays, quota issues, or controller problems.

Quick fix

Fixes load balancer pending ip

kubectl get svc <service-name> -o wide
kubectl get svc <service-name> -o jsonpath='{.metadata.creationTimestamp}'
  1. Check how long the service has been pending
  2. Verify cloud provider controller is running
  3. Review controller logs for load balancer errors
  4. Check cloud provider account quotas
kubernetes โ€” error
kubectl get svc <service-name> -o wide
kubectl get svc <service-name> -o jsonpath='{.metadata.creationTimestamp}'
load balancer pending ip

What this error means

When you create a LoadBalancer service, Kubernetes: 1. Requests external IP from cloud provider 2. Cloud provider allocates IP and creates load balancer 3. Service status updates with EXTERNAL-IP If status stays "pending": - Cloud provider has not allocated IP - Load balancer creation is in progress (normal for 1-2 minutes) - Load balancer creation failed (will stay pending indefinitely) - Cloud provider controller is not running - Quota or IAM permissions are insufficient

Typical symptoms

  • kubectl get svc shows EXTERNAL-IP as "<pending>"
  • Service status.loadBalancer.ingress is empty
  • Waiting for external IP longer than normal (> 5 minutes)
  • kubectl describe svc shows "Pending -> Valid" condition failing
  • Cloud provider logs show load balancer creation errors
  • Events mention "failed to allocate" or "waiting for provider"
  • Service works internally (ClusterIP) but not externally

Common causes

  1. Cloud provider load balancer controller is not running
  2. Network subnet exhaustion (no available IPs)
  3. Service configuration requires manual approval (some clouds)
  4. Cloud provider temporary service degradation
  5. IAM permissions insufficient to create load balancer
  6. Quota exceeded (max load balancers per account)
  7. Service annotation missing or incorrect

How to fix "load balancer pending ip"

1Check how long the service has been pending

Get service creation time:

bash
kubectl get svc <service-name> -o wide
kubectl get svc <service-name> -o jsonpath='{.metadata.creationTimestamp}'

Normal behavior:
- Cloud provider load balancer creation takes 1-5 minutes
- Small additional delay for health checks

If pending for > 10 minutes, something is wrong.

Check for recent events:

bash
kubectl describe svc <service-name>

Look at the Events section:
- Recent events show latest errors
- If no events, controller may not be running
- If events are old (> 5 minutes), controller stuck

2Verify cloud provider controller is running

Check if cloud provider's load balancer controller exists:

AWS:

bash
kubectl get deployment -n kube-system aws-load-balancer-controller
kubectl get pods -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller
kubectl logs -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller

GCP/GKE:

bash
kubectl get pods -n kube-system -l k8s-app=gke-metrics-agent
kubectl logs -n kube-system -l k8s-app=gke-metrics-agent

Azure/AKS:

bash
kubectl get pods -n kube-system -l app=cloud-node-manager
kubectl logs -n kube-system -l app=cloud-provider-azure

If controller is not running or crashing (CrashLoopBackOff):

bash
kubectl describe pod <controller-pod> -n kube-system
kubectl logs <controller-pod> -n kube-system --previous

Reinstall if needed (varies by provider).

3Review controller logs for load balancer errors

Get detailed error information:

AWS:

bash
kubectl logs -n kube-system deployment/aws-load-balancer-controller | tail -100
kubectl logs -n kube-system deployment/aws-load-balancer-controller | grep -i <service-name>
kubectl logs -n kube-system deployment/aws-load-balancer-controller | grep -i error

GCP:

bash
kubectl logs -n kube-system -l k8s-app=gke-metrics-agent | grep -i error
gcloud logging read "resource.type=k8s_cluster and jsonPayload.message=~"load.*balancer"" --limit 50

Azure:

bash
kubectl logs -n kube-system -l app=cloud-provider-azure | grep -i error
az aks get-credentials --resource-group <rg> --name <cluster>
kubectl logs -n kube-system -l component=cloud-node-manager | grep -i error

Common errors:
- "quota exceeded"
- "unauthorized"
- "subnet exhausted"
- "failed to create"
- "rate limited"

4Check cloud provider account quotas

Verify quotas are not exceeded:

AWS:

bash
aws ec2 describe-account-attributes
aws elb describe-load-balancers | grep "LoadBalancerName" | wc -l
aws service-quotas get-service-quota \
  --service-code elasticloadbalancing \
  --quota-code L-E9E9831D  # Load Balancers quota

GCP:

bash
gcloud compute resource-settings list
gcloud compute forwarding-rules list
gcloud compute addresses list

Azure:

bash
az network lb list --output table
az vm list-usage --location <region>
az account get-access-token

If quota exceeded, request increase from cloud provider (AWS/GCP/Azure dashboards).

5Verify IAM permissions

Ensure the cluster has permissions to create load balancers:

AWS IAM:

bash
# Get node role
aws ec2 describe-instances --instance-ids <instance-id> \
  --query "Instances[0].IamInstanceProfile.Arn"

# Check role policies
aws iam list-attached-role-policies --role-name <role>

# Check for required policy
aws iam get-role-policy --role-name <role> --policy-name <policy>

Required permissions:

json
{
  "Effect": "Allow",
  "Action": [
    "elasticloadbalancing:CreateLoadBalancer",
    "elasticloadbalancing:DescribeLoadBalancers",
    "ec2:AllocateAddress",
    "ec2:DescribeSubnets"
  ],
  "Resource": "*"
}

GCP Service Account:

bash
kubectl get sa -n kube-system
gcloud projects get-iam-policy <project>

Azure Identity:

bash
kubectl get pod -n kube-system -o jsonpath='{.items[*].spec.containers[*].env[?(@.name=="MSI_ID")].value}'
az role assignment list --assignee <principal-id>
6Check for subnet/IP exhaustion

Verify subnets have available IPs:

AWS VPC Subnets:

bash
aws ec2 describe-subnets --filters "Name=vpc-id,Values=<vpc-id>" \
  --query "Subnets[*].[SubnetId,AvailableIpAddressCount,CidrBlock]"

If AvailableIpAddressCount is low (< 10), expand CIDR or create new subnet.

GCP Subnets:

bash
gcloud compute networks subnets list --network=<network> \
  --format="table(name,ipCidrRange,privateIpAddress)"

Azure Subnets:

bash
az network vnet subnet show -g <rg> -n <subnet> --vnet-name <vnet>
az network vnet subnet list-available-ips -g <rg> -n <subnet> --vnet-name <vnet>

If subnets exhausted, create new subnets with larger CIDR ranges.

7Check service configuration for cloud-specific settings

Review service annotations:

bash
kubectl get svc <service-name> -o yaml | grep -A20 "metadata:"

Common annotations:

AWS:

yaml
metadata:
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: "nlb"  # Must be nlb or classic
    service.beta.kubernetes.io/aws-load-balancer-subnets: "subnet-12345,subnet-67890"
spec:
  type: LoadBalancer

GCP:

yaml
metadata:
  annotations:
    cloud.google.com/load-balancer-type: "External"  # Or "Internal"

Azure:

yaml
metadata:
  annotations:
    service.beta.kubernetes.io/azure-load-balancer-internal: "false"  # Public LB

Incorrect or missing annotations may prevent load balancer creation. Verify against cloud provider documentation.

8Wait for cloud provider or force refresh

If controller is running and configuration is correct, sometimes it just needs time:

bash
# Monitor status
kubectl get svc <service-name> -w

If it allocates IP within 5-10 minutes, normal behavior.

If still pending after 10 minutes, force a refresh:

Delete and recreate the service:

bash
kubectl delete svc <service-name>
kubectl apply -f service.yaml  # Wait a few minutes

Or trigger controller reconciliation:

bash
# Restart the load balancer controller
kubectl rollout restart deployment/aws-load-balancer-controller -n kube-system

# Annotate service to trigger update
kubectl annotate service <service-name> version="$(date +%s)" --overwrite

Monitor controller logs during reconciliation:

bash
kubectl logs -n kube-system deployment/aws-load-balancer-controller -f

Advanced notes

LoadBalancer IP allocation is eventually consistent; expecting immediate IP assignment (within 1 minute) is usually safe but not guaranteed. Cloud provider degradation (rare) can delay allocation by hours. For mission-critical services, implement readiness probes that check EXTERNAL-IP assignment before marking service ready. Network complexity (multiple VPCs, cross-region) may require manual configurationโ€”consult cloud provider networking docs. Service mesh (Istio, Linkerd) can manage load balancing independently of cloud provider, useful for multi-cloud deployments. For performance-critical applications, use cloud provider's native load balancer directly instead of Kubernetes LoadBalancer abstraction. Monitoring external IP assignment with Prometheus helps catch quota exhaustion early. Cost of LoadBalancer services adds upโ€”implement cost tracking and use Ingress where possible.

Frequently asked questions

What does "load balancer pending ip" mean?
When you create a LoadBalancer service, Kubernetes: 1. Requests external IP from cloud provider 2. Cloud provider allocates IP and creates load balancer 3.
How do I fix "load balancer pending ip"?
LoadBalancer services stuck in "pending" state cannot assign external IPs. This blocks external traffic and prevents service exposure. Usually caused by cloud provider delays, quota issues, or controller problems.
What causes "load balancer pending ip"?
Cloud provider load balancer controller is not running Network subnet exhaustion (no available IPs) Service configuration requires manual approval (some clouds)
Is the "load balancer pending ip" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading