kubernetes/kops · error

unable to detect default launch spec: multiple instance grou

Error message

unable to detect default launch spec: multiple instance groups labeled with `spotinst.ocean/default-launch-spec: "true"`

What it means

When the Spotinst Ocean feature flag is enabled, buildOcean scans node instance groups for the label spotinst.ocean/default-launch-spec to choose which group becomes Ocean's default launch spec. If two or more node groups carry the label with value "true", the default launch spec is ambiguous and the build fails immediately.

Source

Thrown at pkg/model/awsmodel/spotinst.go:386

	if featureflag.SpotinstOceanTemplate.Enabled() {
		ocean.UseAsTemplateOnly = new(true)
	}

	if len(igs) == 0 {
		return nil
	}
	var ig *kops.InstanceGroup
	for _, g := range igs {
		for k, v := range g.ObjectMeta.Labels {
			if k == SpotInstanceGroupLabelOceanDefaultLaunchSpec {
				defaultLaunchSpec, err := parseBool(v)
				if err != nil {
					continue
				}
				if fi.ValueOf(defaultLaunchSpec) {
					if ig != nil {
						return fmt.Errorf("unable to detect default launch spec: "+
							"multiple instance groups labeled with `%s: \"true\"`",
							SpotInstanceGroupLabelOceanDefaultLaunchSpec)
					}
					ig = g.DeepCopy()
					break
				}
			}
		}
	}
	if ig == nil {
		ig = igs[0].DeepCopy()
	}

	klog.V(4).Infof("Detected default launch spec: %q", b.AutoscalingGroupName(ig))

	for k, v := range b.Cluster.Labels {
		switch k {
		case SpotClusterLabelSpreadNodesBy:

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Run `kops get instancegroups` / inspect cluster.yaml and remove `spotinst.ocean/default-launch-spec: "true"` from all but one node group.
  2. Keep the label on the group whose spec should seed Ocean's default launch spec (fall back is the first group if none is labeled).
  3. Apply the change (`kops replace -f ig.yaml` or `kops update cluster`) and re-run the update.
  4. Audit any templates/automation that inject this label so only one group ever gets it.

Example fix

// before (second node group)
metadata:
  labels:
    spotinst.ocean/default-launch-spec: "true"
// after (label removed or set false)
metadata:
  labels: {}
Defensive patterns

Strategy: validation

Validate before calling

labeled := 0
for _, ig := range instanceGroups {
  if ig.ObjectMeta.Labels["spotinst.ocean/default-launch-spec"] == "true" {
    labeled++
  }
}
if labeled > 1 {
  return fmt.Errorf("%d instance groups labeled as ocean default launch spec; keep exactly one", labeled)
}

Try / catch

if err := kopsUpdate(); err != nil {
  if strings.Contains(err.Error(), "unable to detect default launch spec") {
    // strip the label from all but one node group and retry
  }
}

Prevention

When it happens

Trigger: `kops update cluster` with SpotinstOcean enabled where at least two node InstanceGroups have metadata label `spotinst.ocean/default-launch-spec: "true"` on their ObjectMeta.Labels.

Common situations: Cloning an existing labeled node group without removing the label; applying instance group YAMLs where each carries the default-launch-spec label; automation templating that stamps the label on every IG.

Related errors


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