{"record":{"id":"cab674d545a87862","repo":"kubernetes/kops","slug":"load-balancer-is-not-yet-active-current-status","errorCode":null,"errorMessage":"load-balancer is not yet active (current status: %s)","messagePattern":"load-balancer is not yet active \\(current status: (.+?)\\)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"upup/pkg/fi/cloudup/do/cloud.go","lineNumber":290,"sourceCode":"func (c *doCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([]fi.ApiIngressStatus, error) {\n\tvar ingresses []fi.ApiIngressStatus\n\tdone, err := vfs.RetryWithBackoff(readBackoff, func() (bool, error) {\n\t\t// Note that this must match Digital Ocean's lb name\n\t\tklog.V(2).Infof(\"Querying DO to find Loadbalancers for API (%q)\", cluster.Name)\n\n\t\tloadBalancers, err := c.GetAllLoadBalancers()\n\t\tif err != nil {\n\t\t\treturn false, fmt.Errorf(\"LoadBalancers.List returned error: %v\", err)\n\t\t}\n\n\t\tlbName := \"api-\" + strings.ReplaceAll(cluster.Name, \".\", \"-\")\n\n\t\tfor _, lb := range loadBalancers {\n\t\t\tif lb.Name == lbName {\n\t\t\t\tklog.V(10).Infof(\"Matching LB name found for API (%q)\", cluster.Name)\n\n\t\t\t\tif lb.Status != \"active\" {\n\t\t\t\t\treturn false, fmt.Errorf(\"load-balancer is not yet active (current status: %s)\", lb.Status)\n\t\t\t\t}\n\n\t\t\t\taddress := lb.IP\n\t\t\t\tingresses = append(ingresses, fi.ApiIngressStatus{IP: address})\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\t})\n\tif done {\n\t\treturn ingresses, nil\n\t} else {\n\t\tif err == nil {\n\t\t\terr = wait.ErrWaitTimeout\n\t\t}\n\t\treturn ingresses, err\n\t}\n}\n","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/do/cloud.go#L272-L308","documentation":"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.","triggerScenarios":"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'.","commonSituations":"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.","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."],"exampleFix":"null","handlingStrategy":"retry","validationCode":"// check LB status before reading ingress\nlbs, _ := client.LoadBalancers.List(context.TODO(), nil)\nfor _, lb := range lbs {\n    if lb.Name == lbName && lb.Status == \"active\" { /* ready */ }\n}","typeGuard":null,"tryCatchPattern":"ingress, err := cloud.GetApiIngressStatus(cluster)\nif err != nil && strings.Contains(err.Error(), \"not yet active\") {\n    time.Sleep(30 * time.Second); retry() // LB still provisioning\n}","preventionTips":["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."],"tags":["digitalocean","loadbalancer","provisioning","retry"],"backgroundTag":"load-balancer-not-ready","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}