{"record":{"id":"052d3d957648e582","repo":"kubernetes/kops","slug":"unable-to-detect-default-launch-spec-multiple-ins","errorCode":null,"errorMessage":"unable to detect default launch spec: multiple instance groups labeled with `spotinst.ocean/default-launch-spec: \"true\"`","messagePattern":"unable to detect default launch spec: multiple instance groups labeled with `spotinst\\.ocean/default-launch-spec: \"true\"`","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/model/awsmodel/spotinst.go","lineNumber":386,"sourceCode":"\n\tif featureflag.SpotinstOceanTemplate.Enabled() {\n\t\tocean.UseAsTemplateOnly = new(true)\n\t}\n\n\tif len(igs) == 0 {\n\t\treturn nil\n\t}\n\tvar ig *kops.InstanceGroup\n\tfor _, g := range igs {\n\t\tfor k, v := range g.ObjectMeta.Labels {\n\t\t\tif k == SpotInstanceGroupLabelOceanDefaultLaunchSpec {\n\t\t\t\tdefaultLaunchSpec, err := parseBool(v)\n\t\t\t\tif err != nil {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif fi.ValueOf(defaultLaunchSpec) {\n\t\t\t\t\tif ig != nil {\n\t\t\t\t\t\treturn fmt.Errorf(\"unable to detect default launch spec: \"+\n\t\t\t\t\t\t\t\"multiple instance groups labeled with `%s: \\\"true\\\"`\",\n\t\t\t\t\t\t\tSpotInstanceGroupLabelOceanDefaultLaunchSpec)\n\t\t\t\t\t}\n\t\t\t\t\tig = g.DeepCopy()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif ig == nil {\n\t\tig = igs[0].DeepCopy()\n\t}\n\n\tklog.V(4).Infof(\"Detected default launch spec: %q\", b.AutoscalingGroupName(ig))\n\n\tfor k, v := range b.Cluster.Labels {\n\t\tswitch k {\n\t\tcase SpotClusterLabelSpreadNodesBy:","sourceCodeStart":368,"sourceCodeEnd":404,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/model/awsmodel/spotinst.go#L368-L404","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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.","solutions":["Run `kops get instancegroups` / inspect cluster.yaml and remove `spotinst.ocean/default-launch-spec: \"true\"` from all but one node group.","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).","Apply the change (`kops replace -f ig.yaml` or `kops update cluster`) and re-run the update.","Audit any templates/automation that inject this label so only one group ever gets it."],"exampleFix":"// before (second node group)\nmetadata:\n  labels:\n    spotinst.ocean/default-launch-spec: \"true\"\n// after (label removed or set false)\nmetadata:\n  labels: {}","handlingStrategy":"validation","validationCode":"labeled := 0\nfor _, ig := range instanceGroups {\n  if ig.ObjectMeta.Labels[\"spotinst.ocean/default-launch-spec\"] == \"true\" {\n    labeled++\n  }\n}\nif labeled > 1 {\n  return fmt.Errorf(\"%d instance groups labeled as ocean default launch spec; keep exactly one\", labeled)\n}","typeGuard":null,"tryCatchPattern":"if err := kopsUpdate(); err != nil {\n  if strings.Contains(err.Error(), \"unable to detect default launch spec\") {\n    // strip the label from all but one node group and retry\n  }\n}","preventionTips":["Label exactly one node group as the Ocean default launch spec.","When cloning node groups, strip spotinst.ocean labels from the copy.","Add a CI check that counts default-launch-spec labels across instance groups."],"tags":["spotinst","ocean","labels","ambiguous-config"],"backgroundTag":"ambiguous-default-launch-spec","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"}