{"record":{"id":"13cd2d9595ec018d","repo":"kubernetes/kops","slug":"error-patching-status-w","errorCode":null,"errorMessage":"error patching status: %w","messagePattern":"error patching status: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/controllers/clusterapi/kopsconfig_controller.go","lineNumber":107,"sourceCode":"\t\treturn ctrl.Result{}, err\n\t}\n\n\tkopsControlPlane, err := getKopsControlPlaneFromCAPICluster(ctx, r.client, capiCluster)\n\tif err != nil {\n\t\treturn ctrl.Result{}, err\n\t}\n\n\tdata, err := r.buildBootstrapData(ctx, cluster, kopsControlPlane)\n\tif err != nil {\n\t\treturn ctrl.Result{}, err\n\t}\n\n\tif err := r.storeBootstrapData(ctx, obj, data); err != nil {\n\t\treturn ctrl.Result{}, err\n\t}\n\n\tif err := r.client.Status().Update(ctx, obj); err != nil {\n\t\treturn ctrl.Result{}, fmt.Errorf(\"error patching status: %w\", err)\n\t}\n\treturn ctrl.Result{}, nil\n}\n\n// storeBootstrapData creates a new secret with the data passed in as input,\n// sets the reference in the configuration status and ready to true.\nfunc (r *KopsConfigReconciler) storeBootstrapData(ctx context.Context, parent *api.KopsConfig, data []byte) error {\n\t// log := ctrl.LoggerFrom(ctx)\n\n\tclusterName := parent.Labels[clusterv1.ClusterNameLabel]\n\n\tif clusterName == \"\" {\n\t\treturn fmt.Errorf(\"cluster name label %q not yet set\", clusterv1.ClusterNameLabel)\n\t}\n\n\tsecretName := types.NamespacedName{\n\t\tNamespace: parent.GetNamespace(),\n\t\tName:      parent.GetName(),","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/controllers/clusterapi/kopsconfig_controller.go#L89-L125","documentation":"In the KopsConfig bootstrap controller's Reconcile, after storing the bootstrap-data secret, the controller updates the KopsConfig object's status (DataSecretName, Ready) with client.Status().Update. This error wraps any failure of that status update — most commonly an optimistic-concurrency conflict because the object changed since it was fetched.","triggerScenarios":"The KopsConfig object was modified (resourceVersion bumped) between the initial Get and the Status().Update, producing a Conflict; the ServiceAccount lacks update permission on kopsconfigs/status; the API server rejects or times out the request.","commonSituations":"Frequent reconcile storms where the object is edited concurrently by another controller or user; controller RBAC missing status-update verbs; API server slowness/etcd timeouts.","solutions":["Simply requeue — controller-runtime retries and the conflict resolves on the next reconcile with fresh resourceVersion","Use a merge patch (client.Status().Patch with client.MergeFrom) to reduce conflict likelihood","Grant update/patch on kopsconfigs/status to the controller ServiceAccount","Check API-server health/etcd latency if conflicts persist at scale"],"exampleFix":"// before\nif err := r.client.Status().Update(ctx, obj); err != nil {\n    return ctrl.Result{}, fmt.Errorf(\"error patching status: %w\", err)\n}\n// after: use patch to reduce optimistic-concurrency conflicts\npatch := client.MergeFrom(obj.DeepCopy())\nobj.Status.DataSecretName = pointer.String(secret.Name)\nobj.Status.Ready = true\nif err := r.client.Status().Patch(ctx, obj, patch); err != nil {\n    if apierrors.IsConflict(err) {\n        return ctrl.Result{RequeueAfter: time.Second}, nil\n    }\n    return ctrl.Result{}, fmt.Errorf(\"error patching status: %w\", err)\n}","handlingStrategy":"retry","validationCode":"kubectl auth can-i patch kopsconfigs.status -n <ns> --as=system:serviceaccount:<ns>:<sa>\n# or: kubectl auth can-i update kopsconfigs/status ...","typeGuard":null,"tryCatchPattern":"if err := r.client.Status().Update(ctx, obj); err != nil {\n    if apierrors.IsConflict(err) {\n        return ctrl.Result{Requeue: true}, nil // stale resourceVersion, retry with fresh copy\n    }\n    return ctrl.Result{}, fmt.Errorf(\"error patching status: %w\", err)\n}","preventionTips":["Prefer Status().Patch with MergeFrom over Update to reduce conflicts","Avoid external writers touching KopsConfig status","Requeue on conflict instead of surfacing an error","Check etcd/API-server latency if conflicts are persistent"],"tags":["kubernetes","status-update","conflict","controller"],"backgroundTag":"object-conflict-resourceversion","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"}