{"record":{"id":"2c7da5d5b5b3889e","repo":"kubernetes/kops","slug":"failed-to-deregister-instance-from-load-balancers","errorCode":null,"errorMessage":"failed to deregister instance from load balancers: %v","messagePattern":"failed to deregister instance from load balancers: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/awsup/aws_cloud.go","lineNumber":548,"sourceCode":"\tloadBalancerNames := asgDetails.AutoScalingGroups[0].LoadBalancerNames\n\ttargetGroupArns := asgDetails.AutoScalingGroups[0].TargetGroupARNs\n\n\teg, _ := errgroup.WithContext(context.Background())\n\n\tif len(loadBalancerNames) != 0 {\n\t\teg.Go(func() error {\n\t\t\treturn deregisterInstanceFromClassicLoadBalancer(ctx, c, loadBalancerNames, i.ID)\n\t\t})\n\t}\n\n\tif len(targetGroupArns) != 0 {\n\t\teg.Go(func() error {\n\t\t\treturn deregisterInstanceFromTargetGroups(ctx, c, targetGroupArns, i.ID)\n\t\t})\n\t}\n\n\tif err := eg.Wait(); err != nil {\n\t\treturn fmt.Errorf(\"failed to deregister instance from load balancers: %v\", err)\n\t}\n\n\treturn nil\n}\n\n// deregisterInstanceFromClassicLoadBalancer ensures that connectionDraining completes for the associated classic loadBalancer to ensure no dropped connections.\nfunc deregisterInstanceFromClassicLoadBalancer(ctx context.Context, c AWSCloud, loadBalancerNames []string, instanceId string) error {\n\tklog.Infof(\"Deregistering instance from classic loadBalancers: %v\", loadBalancerNames)\n\n\tfor {\n\t\tinstanceDraining := false\n\t\tfor _, loadBalancerName := range loadBalancerNames {\n\t\t\tresponse, err := c.ELB().DescribeInstanceHealth(ctx, &elb.DescribeInstanceHealthInput{\n\t\t\t\tLoadBalancerName: aws.String(loadBalancerName),\n\t\t\t\tInstances: []elbtypes.Instance{{\n\t\t\t\t\tInstanceId: aws.String(instanceId),\n\t\t\t\t}},\n\t\t\t})","sourceCodeStart":530,"sourceCodeEnd":566,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/awsup/aws_cloud.go#L530-L566","documentation":"After describing the ASG, deregisterInstance drains the instance concurrently from all Classic ELBs and all target groups using an errgroup; if ANY of those goroutines fails, the aggregated error is wrapped with this message. The instance is not considered safe to terminate. Note the wording can be misleading — target-group failures also surface here (nested under the 'failed to register instance from targetGroups' error).","triggerScenarios":"eg.Wait() returns non-nil because deregisterInstanceFromClassicLoadBalancer hit a DescribeInstanceHealth error, or deregisterInstanceFromTargetGroups hit a DescribeTargetHealth/DeregisterTargets error, for any of the ASG's load balancers.","commonSituations":"Missing ELB/ELBv2 IAM permissions; a load balancer referenced by the ASG was deleted out-of-band; deregistration draining loop interrupted by API errors; throttling with many LBs/target groups attached.","solutions":["Read the nested wrapped error to see whether the Classic ELB or target group path failed and which LB/TG","Grant elb:DescribeInstanceHealth, elb:DeregisterInstancesFromLoadBalancer, elasticloadbalancing:DescribeTargetHealth, elasticloadbalancing:DeregisterTargets in IAM","Verify all load balancers/target groups on the ASG exist; detach deleted ones from the ASG","Retry after transient API errors; consider draining manually via AWS console before deleting the instance"],"exampleFix":"// before: nested error shows cause\n// failed to deregister instance from load balancers: failed to register instance from targetGroups: error describing target health: AccessDenied\n// after: fix IAM\n{\"Effect\":\"Allow\",\"Action\":[\"elasticloadbalancing:DescribeTargetHealth\",\"elasticloadbalancing:DeregisterTargets\",\"elasticloadbalancing:DescribeInstanceHealth\",\"elasticloadbalancing:DeregisterInstancesFromLoadBalancer\"],\"Resource\":\"*\"}","handlingStrategy":"try-catch","validationCode":"// verify all LBs/TGs on the ASG still exist before draining\nfor _, tgArn := range asg.TargetGroupARNs {\n\tif _, err := elbv2Svc.DescribeTargetGroups(&elbv2.DescribeTargetGroupsInput{TargetGroupArns: []string{tgArn}}); err != nil {\n\t\treturn fmt.Errorf(\"stale target group %s on ASG: %w\", tgArn, err)\n\t}\n}","typeGuard":"func isDeregistrationErr(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"failed to deregister instance from load balancers\")\n}","tryCatchPattern":"if err := cloud.DeregisterInstance(inst); err != nil {\n\tklog.Errorf(\"LB drain failed for %s: %v\", inst.ID, err)\n\t// inspect nested cause: classic ELB vs target group failure, then fix IAM or stale LB refs\n\treturn err\n}","preventionTips":["Pre-flight check that every LB/TG on the ASG exists","Keep ELB + ELBv2 permissions in one IAM policy for kOps","Run rolling updates serially on clusters with many attached load balancers","Treat this as unsafe-to-terminate: never force-delete the instance without draining"],"tags":["aws","load-balancer","drain","concurrency"],"backgroundTag":"load-balancer-deregistration-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"}