{"record":{"id":"d499543bd880d0fd","repo":"tailscale/tailscale","slug":"failed-to-apply-statefulset-w","errorCode":null,"errorMessage":"failed to apply StatefulSet: %w","messagePattern":"failed to apply StatefulSet: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"k8s-operator/reconciler/peerrelay/peerrelay.go","lineNumber":513,"sourceCode":"\t\tif err := r.Delete(ctx, secret); err != nil && !apierrors.IsNotFound(err) {\n\t\t\treturn fmt.Errorf(\"failed to delete config Secret %q: %w\", secret.Name, err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (r *Reconciler) ensureStatefulSet(ctx context.Context, logger *zap.SugaredLogger, pr *tsapi.PeerRelay, replicas int32) (*appsv1.StatefulSet, error) {\n\tpc, err := r.getProxyClass(ctx, pr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tdesired := r.peerRelayStatefulSet(pr, replicas, pc)\n\n\tlogger.Debugf(\"applying StatefulSet %q\", desired.Name)\n\tif err = r.Patch(ctx, desired, client.Apply, fieldOwner, client.ForceOwnership); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to apply StatefulSet: %w\", err)\n\t}\n\n\tvar current appsv1.StatefulSet\n\tif err = r.Get(ctx, types.NamespacedName{Namespace: desired.Namespace, Name: desired.Name}, &current); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get StatefulSet: %w\", err)\n\t}\n\n\treturn &current, nil\n}\n\nfunc (r *Reconciler) deleteStatefulSet(ctx context.Context, logger *zap.SugaredLogger, pr *tsapi.PeerRelay) error {\n\tss := &appsv1.StatefulSet{\n\t\tObjectMeta: metav1.ObjectMeta{Name: resourceName(pr.Name), Namespace: r.tailscaleNamespace},\n\t}\n\tlogger.Debugf(\"deleting StatefulSet %q\", ss.Name)\n\tif err := r.Delete(ctx, ss); err != nil && !apierrors.IsNotFound(err) {\n\t\treturn fmt.Errorf(\"failed to delete StatefulSet: %w\", err)\n\t}","sourceCodeStart":495,"sourceCodeEnd":531,"githubUrl":"https://github.com/tailscale/tailscale/blob/6e0912f97994f927632b34ae9e63b53d6516a6ac/k8s-operator/reconciler/peerrelay/peerrelay.go#L495-L531","documentation":"Raised in ensureStatefulSet when server-side apply of the PeerRelay's StatefulSet fails. The ProxyClass was already resolved and merged; a validation rejection from the API server, admission webhook, or RBAC gap produces this.","triggerScenarios":"Thrown at k8s-operator/reconciler/peerrelay/peerrelay.go:513 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Applying the StatefulSet failed; validate the StatefulSet spec and RBAC permissions, then retry."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"6e0912f97994f927632b34ae9e63b53d6516a6ac","analyzedAt":"2026-08-18T08:17:25.280Z","contentChangedAt":"2026-08-18T08:17:25.280Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}