{"record":{"id":"a92087d1af5645ea","repo":"kubernetes/kops","slug":"error-writing-updated-instancegroup-configuration","errorCode":null,"errorMessage":"error writing updated instancegroup configuration: %v","messagePattern":"error writing updated instancegroup configuration: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/apis/kops/registry/helpers.go","lineNumber":52,"sourceCode":"\t\t\tif ns.ObjectMeta.Name == \"\" {\n\t\t\t\treturn fmt.Errorf(\"InstanceGroup #%d did not have a Name\", i+1)\n\t\t\t}\n\t\t\tif names[ns.ObjectMeta.Name] {\n\t\t\t\treturn fmt.Errorf(\"duplicate InstanceGroup Name found: %q\", ns.ObjectMeta.Name)\n\t\t\t}\n\t\t\tnames[ns.ObjectMeta.Name] = true\n\t\t}\n\t}\n\n\t_, err := clientset.CreateCluster(ctx, cluster)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfor _, ig := range groups {\n\t\t_, err = clientset.InstanceGroupsFor(cluster).Create(ctx, ig, metav1.CreateOptions{})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error writing updated instancegroup configuration: %v\", err)\n\t\t}\n\t}\n\n\t{\n\t\taddonsClient := clientset.AddonsFor(cluster)\n\n\t\tif err := addonsClient.Replace(addons); err != nil {\n\t\t\treturn fmt.Errorf(\"error writing updated addon configuration: %v\", err)\n\t\t}\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":34,"sourceCodeEnd":66,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/apis/kops/registry/helpers.go#L34-L66","documentation":"CreateClusterConfig in pkg/apis/kops/registry/helpers.go writes each InstanceGroup via clientset.InstanceGroupsFor(cluster).Create after the cluster itself has been created. When any single InstanceGroup create fails against the cluster's backing store (state store), the error is wrapped as \"error writing updated instancegroup configuration\" and creation aborts, potentially leaving a partially provisioned cluster (cluster exists, some instance groups missing).","triggerScenarios":"Calling CreateClusterConfig (via `kops create cluster`) when an InstanceGroup with the same name already exists in the state store (AlreadyExists), the state store is unreachable/misconfigured (e.g. bad S3 bucket/permissions), or the VFS path for the cluster cannot be written.","commonSituations":"Re-running `kops create cluster` against an existing cluster state without `--force` semantics; expired or missing cloud credentials (AWS S3 403); wrong --state flag pointing at a bucket holding stale instancegroups; network outage during cluster creation.","solutions":["Inspect the wrapped %v cause: if it is AlreadyExists, delete/adopt the existing cluster state or use `kops replace`/`kops create -f` update instead of create.","Verify --state (ConfigStore.Base) points to a writable, existing store and credentials are valid (`kops get clusters` as smoke test).","Delete partially created cluster state (`kops delete cluster --name <name> --yes`) and retry creation.","If transient (network/IO), retry CreateClusterConfig; note instance groups created before the failure are not rolled back automatically."],"exampleFix":"// before\n_, err = clientset.InstanceGroupsFor(cluster).Create(ctx, ig, metav1.CreateOptions{})\n// after\nexisting, getErr := clientset.InstanceGroupsFor(cluster).Get(ctx, ig.Name, metav1.GetOptions{})\nif getErr == nil && existing != nil {\n\t_, err = clientset.InstanceGroupsFor(cluster).Update(ctx, ig, metav1.UpdateOptions{})\n} else {\n\t_, err = clientset.InstanceGroupsFor(cluster).Create(ctx, ig, metav1.CreateOptions{})\n}","handlingStrategy":"try-catch","validationCode":"names := map[string]bool{}\nfor _, ig := range groups {\n\tif ig.Name == \"\" || names[ig.Name] {\n\t\treturn fmt.Errorf(\"invalid or duplicate instancegroup name %q\", ig.Name)\n\t}\n\tnames[ig.Name] = true\n}\n// also verify state store reachable/writable before creating\nif _, err := clientset.GetCluster(ctx, cluster); err == nil {\n\treturn fmt.Errorf(\"cluster %q already exists in state store\", cluster.Name)\n}","typeGuard":"func isAlreadyExists(err error) bool {\n\tvar apiErr apierrors.APIStatus\n\tif errors.As(err, &apiErr) {\n\t\treturn apiErr.Status().Reason == metav1.StatusReasonAlreadyExists\n\t}\n\treturn false\n}","tryCatchPattern":"_, err := clientset.InstanceGroupsFor(cluster).Create(ctx, ig, metav1.CreateOptions{})\nif err != nil {\n\tif isAlreadyExists(err) {\n\t\t_, err = clientset.InstanceGroupsFor(cluster).Update(ctx, ig, metav1.UpdateOptions{})\n\t}\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error writing updated instancegroup configuration: %v\", err)\n\t}\n}","preventionTips":["Check for an existing cluster in the state store before running create.","Validate instance group names are unique and non-empty before calling CreateClusterConfig.","Confirm state-store credentials and bucket writability with a cheap read/write smoke test.","Handle AlreadyExists by falling back to Update instead of retrying Create blindly."],"tags":["state-store","instancegroup","cluster-creation","persistence"],"backgroundTag":"state-store-write-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"}