{"record":{"id":"6c034d96c2b3cf78","repo":"tailscale/tailscale","slug":"error-deleting-role-for-domain-name-s-w","errorCode":null,"errorMessage":"error deleting Role for domain name %s: %w","messagePattern":"error deleting Role for domain name (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"cmd/k8s-operator/ingress-for-pg.go","lineNumber":1009,"sourceCode":"\t}); err != nil {\n\t\treturn fmt.Errorf(\"failed to create or update RoleBinding %s: %w\", rolebinding.Name, err)\n\t}\n\treturn nil\n}\n\n// cleanupCertResources ensures that the TLS Secret and associated RBAC\n// resources that allow proxies to read/write to the Secret are deleted.\nfunc cleanupCertResources(ctx context.Context, cl client.Client, tsNamespace string, serviceName tailcfg.ServiceName, pg *tsapi.ProxyGroup) error {\n\tdomainName, err := dnsNameForService(ctx, cl, serviceName, pg, tsNamespace)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error getting DNS name for Tailscale Service %s: %w\", serviceName, err)\n\t}\n\tlabels := certResourceLabels(pg.Name, domainName)\n\tif err := cl.DeleteAllOf(ctx, &rbacv1.RoleBinding{}, client.InNamespace(tsNamespace), client.MatchingLabels(labels)); err != nil {\n\t\treturn fmt.Errorf(\"error deleting RoleBinding for domain name %s: %w\", domainName, err)\n\t}\n\tif err := cl.DeleteAllOf(ctx, &rbacv1.Role{}, client.InNamespace(tsNamespace), client.MatchingLabels(labels)); err != nil {\n\t\treturn fmt.Errorf(\"error deleting Role for domain name %s: %w\", domainName, err)\n\t}\n\tif err := cl.DeleteAllOf(ctx, &corev1.Secret{}, client.InNamespace(tsNamespace), client.MatchingLabels(labels)); err != nil {\n\t\treturn fmt.Errorf(\"error deleting Secret for domain name %s: %w\", domainName, err)\n\t}\n\treturn nil\n}\n\n// requeueInterval returns a time duration between 5 and 10 minutes, which is\n// the period of time after which an HA Ingress, whose Tailscale Service has been newly\n// created or changed, needs to be requeued. This is to protect against\n// Tailscale Service's owner references being overwritten as a result of concurrent\n// updates during multi-clutster Ingress create/update operations.\nfunc requeueInterval() time.Duration {\n\treturn time.Duration(rand.N(5)+5) * time.Minute\n}\n\n// certSecretRole creates a Role that will allow proxies to manage the TLS\n// Secret for the given domain. Domain must be a valid Kubernetes resource name.","sourceCodeStart":991,"sourceCodeEnd":1027,"githubUrl":"https://github.com/tailscale/tailscale/blob/cfe32b8be6a33f8e24fbc369cbfbf7c729d9e042/cmd/k8s-operator/ingress-for-pg.go#L991-L1027","documentation":"During cert cleanup, cl.DeleteAllOf for Roles labelled with the ProxyGroup name and domain failed — the Role half of the cert RBAC pair. Identical failure modes to the RoleBinding deletion: RBAC denial or apiserver error. Cleanup stops before the Secret deletion step, so resources leak until a successful retry.","triggerScenarios":"cl.DeleteAllOf(ctx, &rbacv1.Role{}, client.InNamespace(tsNamespace), client.MatchingLabels(labels)) after the RoleBinding delete in cleanupCertResources. Fires on missing delete on roles or control-plane errors.","commonSituations":"Narrowed ClusterRole without role delete; admission webhooks blocking collection deletes; overloaded apiserver during cluster teardown.","solutions":["Verify operator can delete roles in its namespace","Let the reconciler retry — DeleteAllOf is idempotent","Manually delete leftovers: kubectl delete role -n <operator-ns> -l tailscale.com/parent-proxy-group=<pgName>"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := cl.DeleteAllOf(ctx, &rbacv1.Role{}, client.InNamespace(ns), client.MatchingLabels(labels)); err != nil {\n    if apierrors.IsNotFound(err) {\n        return nil\n    }\n    return fmt.Errorf(\"error deleting Role for domain name %s: %w\", domainName, err)\n}","preventionTips":["Keep roles.rbac.authorization.k8s.io delete in the operator ClusterRole","Check admission controllers when collection deletes fail consistently","Reconcile leftover labelled Roles during operator upgrades"],"tags":["kubernetes","rbac","cleanup","operator"],"backgroundTag":null,"analyzedSha":"cfe32b8be6a33f8e24fbc369cbfbf7c729d9e042","analyzedAt":"2026-08-15T19:58:31.583Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}