kubernetes/kops · warning
load-balancer is not yet active (current status: %s)
Error message
load-balancer is not yet active (current status: %s)
What it means
Inside the GetApiIngressStatus retry loop, when a load balancer matching 'api-<cluster-name>' is found, its Status field must be 'active'. While DO is still provisioning or reconfiguring the load balancer the status is 'new'/'in-progress', and the closure returns this error so the backoff loop retries until the LB becomes active or retries are exhausted.
Source
Thrown at upup/pkg/fi/cloudup/do/cloud.go:290
func (c *doCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([]fi.ApiIngressStatus, error) {
var ingresses []fi.ApiIngressStatus
done, err := vfs.RetryWithBackoff(readBackoff, func() (bool, error) {
// Note that this must match Digital Ocean's lb name
klog.V(2).Infof("Querying DO to find Loadbalancers for API (%q)", cluster.Name)
loadBalancers, err := c.GetAllLoadBalancers()
if err != nil {
return false, fmt.Errorf("LoadBalancers.List returned error: %v", err)
}
lbName := "api-" + strings.ReplaceAll(cluster.Name, ".", "-")
for _, lb := range loadBalancers {
if lb.Name == lbName {
klog.V(10).Infof("Matching LB name found for API (%q)", cluster.Name)
if lb.Status != "active" {
return false, fmt.Errorf("load-balancer is not yet active (current status: %s)", lb.Status)
}
address := lb.IP
ingresses = append(ingresses, fi.ApiIngressStatus{IP: address})
}
}
return true, nil
})
if done {
return ingresses, nil
} else {
if err == nil {
err = wait.ErrWaitTimeout
}
return ingresses, err
}
}
View on GitHub (pinned to 4c8573c808)
Solutions
- Wait a few minutes and retry — provisioning typically completes and the retry loop will then return the IP.
- If it never goes active, inspect the load balancer in the DO console or `doctl compute load-balancer get` for its real status and error details.
- Check LB backend droplets/forwarding rules are valid; delete and let kOps recreate a broken LB.
- Increase kOps wait/backoff tolerance if your clusters' LBs provision slowly.
Example fix
null
Defensive patterns
Strategy: retry
Validate before calling
// check LB status before reading ingress
lbs, _ := client.LoadBalancers.List(context.TODO(), nil)
for _, lb := range lbs {
if lb.Name == lbName && lb.Status == "active" { /* ready */ }
} Try / catch
ingress, err := cloud.GetApiIngressStatus(cluster)
if err != nil && strings.Contains(err.Error(), "not yet active") {
time.Sleep(30 * time.Second); retry() // LB still provisioning
} Prevention
- Wait for LB 'active' status before consuming the API endpoint.
- Allow generous timeouts after cluster creation (LB provisioning takes minutes).
- Monitor the LB in the DO console if it never becomes active.
- Don't treat this as fatal on first attempt — it's usually transient provisioning.
When it happens
Trigger: Reading the API ingress address immediately after `kops create cluster` or an LB-touching change, while the DigitalOcean load balancer is still provisioning; also when the LB is in an error/degraded state that never becomes 'active'.
Common situations: Waiting for a brand-new cluster's API endpoint; validation scripts that query the endpoint seconds after cluster creation; a stuck/errored LB (e.g. forwarding rules referencing deleted droplets) that stays non-active through every retry.
Related errors
- vpc not yet created..
- LoadBalancers.List returned error: %v
- Failed to get fixed ip for associated pool: %v
- DIGITALOCEAN_ACCESS_TOKEN is required
- DIGITALOCEAN_ACCESS_TOKEN is required
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/cab674d545a87862.
Report an issue: GitHub.