{"record":{"id":"db63944f390066b6","repo":"kubernetes/kops","slug":"error-getting-load-balancer-stats-v","errorCode":null,"errorMessage":"Error getting load balancer stats %v","messagePattern":"Error getting load balancer stats (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/openstack/loadbalancer.go","lineNumber":303,"sourceCode":"\t\t}\n\t\treturn lbs, err\n\t}\n\treturn lbs, nil\n}\n\nfunc (c *openstackCloud) GetLBStats(loadbalancerID string) (stats *loadbalancers.Stats, err error) {\n\treturn getLBStats(c, loadbalancerID)\n}\n\nfunc getLBStats(c OpenstackCloud, loadbalancerID string) (stats *loadbalancers.Stats, err error) {\n\tif c.LoadBalancerClient() == nil {\n\t\treturn stats, nil\n\t}\n\n\tdone, err := vfs.RetryWithBackoff(readBackoff, func() (bool, error) {\n\t\tstats, err = loadbalancers.GetStats(context.TODO(), c.LoadBalancerClient(), loadbalancerID).Extract()\n\t\tif err != nil {\n\t\t\treturn false, fmt.Errorf(\"Error getting load balancer stats %v\", err)\n\t\t}\n\t\treturn true, nil\n\t})\n\tif !done {\n\t\tif err == nil {\n\t\t\terr = wait.ErrWaitTimeout\n\t\t}\n\t\treturn stats, err\n\t}\n\treturn stats, nil\n}\n\nfunc (c *openstackCloud) GetPool(poolID string) (pool *v2pools.Pool, err error) {\n\treturn getPool(c, poolID)\n}\n\nfunc getPool(c OpenstackCloud, poolID string) (pool *v2pools.Pool, err error) {\n\tif c.LoadBalancerClient() == nil {","sourceCodeStart":285,"sourceCodeEnd":321,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/openstack/loadbalancer.go#L285-L321","documentation":"Thrown when `loadbalancers.GetStats(...).Extract()` fails inside a RetryWithBackoff loop while fetching Octavia load balancer statistics. The gophercloud GetStats call either returned a non-2xx HTTP response or its payload could not be extracted. It is retried with backoff, so the surfaced error is the last attempt's failure.","triggerScenarios":"Calling GetLoadbalancerStats with a loadbalancerID for a load balancer that no longer exists (404), the Octavia service is down (5xx), or the project lacks credentials/permissions to view stats.","commonSituations":"A cluster being deleted concurrently while stats are polled; IAM/keystone role missing the octavia viewer role; Octavia API outage or timeouts in a busy cloud.","solutions":["Check the wrapped %v error for the HTTP status: 404 means the LB ID is stale/being deleted and the caller should treat it as gone.","Verify keystone credentials and that the project has access to the load balancer (`openstack loadbalancer stats <id>`).","Confirm the Octavia service is healthy in the cloud region.","Rely on the built-in readBackoff retry; if timeouts persist, increase backoff or poll less frequently."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"lb, err := cloud.GetLoadbalancer(loadbalancerID)\nif err != nil || lb == nil {\n\treturn fmt.Errorf(\"loadbalancer %s not accessible, skip stats\", loadbalancerID)\n}","typeGuard":null,"tryCatchPattern":"stats, err := cloud.GetLoadbalancerStats(id)\nif err != nil {\n\tif strings.Contains(err.Error(), \"404\") || strings.Contains(err.Error(), \"Not Found\") {\n\t\tklog.V(2).Infof(\"LB %s deleted; treating stats as zero\", id)\n\t\treturn defaultStats, nil\n\t}\n\treturn retryStatsWithBackoff(id) // surface only after retries exhausted\n}","preventionTips":["Confirm the LB exists before polling stats; handle 404 as 'gone' not fatal.","Grant the project viewer access to Octavia resources.","Poll stats at modest intervals; the helper already retries via readBackoff."],"tags":["openstack","octavia","stats","api-call"],"backgroundTag":"openstack-api-request-failed","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"}