{"record":{"id":"ac8243aa224574dc","repo":"kubernetes/kops","slug":"deleting-load-balancer-s-w","errorCode":null,"errorMessage":"deleting load-balancer %s: %w","messagePattern":"deleting load-balancer (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/scaleway/cloud.go","lineNumber":568,"sourceCode":"\n\t// We delete the load-balancer once it's in a stable state\n\t_, err := s.lbAPI.WaitForLb(&lb.ZonedAPIWaitForLBRequest{\n\t\tLBID: loadBalancer.ID,\n\t\tZone: s.zone,\n\t})\n\tif err != nil {\n\t\tif is404Error(err) {\n\t\t\tklog.V(8).Infof(\"Load-balancer %q (%s) was already deleted\", loadBalancer.Name, loadBalancer.ID)\n\t\t\treturn nil\n\t\t}\n\t\treturn fmt.Errorf(\"waiting for load-balancer: %w\", err)\n\t}\n\terr = s.lbAPI.DeleteLB(&lb.ZonedAPIDeleteLBRequest{\n\t\tZone: s.zone,\n\t\tLBID: loadBalancer.ID,\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"deleting load-balancer %s: %w\", loadBalancer.ID, err)\n\t}\n\n\t// We wait for the load-balancer to be deleted, then we detach its IPs\n\t_, err = s.lbAPI.WaitForLb(&lb.ZonedAPIWaitForLBRequest{\n\t\tLBID: loadBalancer.ID,\n\t\tZone: s.zone,\n\t})\n\tif !is404Error(err) {\n\t\treturn fmt.Errorf(\"waiting for load-balancer %s after deletion: %w\", loadBalancer.ID, err)\n\t}\n\tfor _, ip := range ipsToRelease {\n\t\terr := s.lbAPI.ReleaseIP(&lb.ZonedAPIReleaseIPRequest{\n\t\t\tZone: s.zone,\n\t\t\tIPID: ip.ID,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"deleting load-balancer IP: %w\", err)\n\t\t}","sourceCodeStart":550,"sourceCodeEnd":586,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/scaleway/cloud.go#L550-L586","documentation":"Wrap-around error from DeleteLoadBalancer when the lb API DeleteLB call itself fails. It fires only if the preceding WaitForLb succeeded (LB exists) but deletion is rejected or errors; the LB ID and SDK error are wrapped with %w.","triggerScenarios":"DeleteLB failure: IAM permission to delete LBs missing, LB still has attached backends/IPs the API refuses to delete, wrong zone in the delete request, API outage or rate limiting.","commonSituations":"kops principal has read but not delete rights on the LB service; LB has private-network attachments or leftover services blocking deletion; zone mismatch after config drift; transient API errors during cluster teardown.","solutions":["Detach remaining LB backends/services/IPs first, or delete them via `scw lb backend delete` / `scw lb ip list`, then retry DeleteLB.","Check IAM permissions for lb deletion for the kops principal.","Verify s.zone matches the LB's zone; a mismatched zone yields not-found/invalid errors.","Retry with backoff on 429/5xx and re-run teardown; check Scaleway status during incidents."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// ensure no backends/services remain that could block LB deletion\nbks, err := lb.NewZonedAPI(client).ListBackends(&lb.ZonedAPIListBackendsRequest{Zone: s.zone, LBID: lbID})\nif err != nil { return err }\nfor _, b := range bks.Backends {\n  _ = lb.NewZonedAPI(client).DeleteBackend(&lb.ZonedAPIDeleteBackendRequest{Zone: s.zone, BackendID: b.ID})\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Grant the kops principal full lb write permissions (delete included).","Detach private-network attachments before LB teardown.","Run `kops delete cluster` once with adequate permissions rather than partial manual cleanup."],"tags":["scaleway","load-balancer","deletion","api-error"],"backgroundTag":"load-balancer-deletion-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}