kubernetes/kops · error

spotinst: load balancer

Error message

spotinst: load balancer %q has no LoadBalancerName

What it means

buildLoadBalancers converts the task's LoadBalancers into spotinst aws.LoadBalancer objects of type CLASSIC, which require a LoadBalancerName. If a configured load balancer has only an ARN/ID and no name, kOps cannot build the CLASSIC LB reference and fails with the LB's name field (which is itself empty in practice).

Solutions

  1. Set loadBalancerName on each attached load balancer in the cluster/instance-group spec, using the classic ELB's name.
  2. If the intent was ALB/NLB attachment, verify your kOps/spotinst task version supports it and use the appropriate field instead of the classic-LB path.
  3. Run `kops get cluster -o yaml`, locate the loadBalancers entries for the elastigroup, and fill the missing name before applying.
  4. Confirm the referenced classic ELB exists in the cluster region.

Example fix

// before
loadBalancers:
- targetGroupArn: arn:aws:elasticloadbalancing:...
// after (classic LB requires a name)
loadBalancers:
- loadBalancerName: my-api-elb
Defensive patterns

Strategy: validation

Validate before calling

// reject LB entries without a classic LB name before building
for i, lb := range e.LoadBalancers {
    if lb.LoadBalancerName == nil || *lb.LoadBalancerName == "" {
        return fmt.Errorf("loadBalancers[%d]: loadBalancerName is required for classic ELB attachment", i)
    }
}

Type guard

func hasLBName(lb *LoadBalancer) bool {
    return lb != nil && lb.LoadBalancerName != nil && *lb.LoadBalancerName != ""
}

Try / catch

lb, err := buildLoadBalancers(cloud)
if err != nil {
    return fmt.Errorf("skipping elastigroup render: %v", err) // fix spec and re-apply
}

Prevention

When it happens

Trigger: Elastigroup spec includes a load balancer entry whose LoadBalancerName is nil — e.g. the spec referenced a target-group/ALB-style attachment without a classic LB name — and buildLoadBalancers runs during terraform-value rendering or group construction.

Common situations: Attaching an ALB/NLB or target group to a spotinst elastigroup spec that only supports CLASSIC LBs by name; load balancer name lost when copying specs between clusters; older spec format migrations.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/5ac1faa2f9bbb527. Report an issue: GitHub.

Appendix: source

Thrown at upup/pkg/fi/cloudup/spotinsttasks/elastigroup.go:1752

}

func (e *Elastigroup) buildAutoScaleLabels(labelsMap map[string]string) []*aws.AutoScaleLabel {
	labels := make([]*aws.AutoScaleLabel, 0, len(labelsMap))
	for key, value := range labelsMap {
		labels = append(labels, &aws.AutoScaleLabel{
			Key:   new(key),
			Value: new(value),
		})
	}

	return labels
}

func (e *Elastigroup) buildLoadBalancers(cloud awsup.AWSCloud) ([]*aws.LoadBalancer, error) {
	lbs := make([]*aws.LoadBalancer, len(e.LoadBalancers))
	for i, lb := range e.LoadBalancers {
		if lb.LoadBalancerName == nil {
			return nil, fmt.Errorf("spotinst: load balancer %q has no LoadBalancerName", fi.ValueOf(lb.GetName()))
		}
		lbs[i] = &aws.LoadBalancer{
			Type: new("CLASSIC"),
			Name: lb.LoadBalancerName,
		}
	}
	return lbs, nil
}

func (e *Elastigroup) buildTargetGroups() []*aws.LoadBalancer {
	tgs := make([]*aws.LoadBalancer, len(e.TargetGroups))
	for i, tg := range e.TargetGroups {
		tgs[i] = &aws.LoadBalancer{
			Type: new("TARGET_GROUP"),
			Arn:  tg.ARN,
		}
	}
	return tgs

View on GitHub (pinned to 4c8573c808)