tailscale/tailscale · error
failed to list ProxyGroup %q state Secrets: %w
Error message
failed to list ProxyGroup %q state Secrets: %w
What it means
Returned when the Kubernetes client cannot List the ProxyGroup's state Secrets (label selector pgSecretLabels(pgName, LabelSecretTypeState)) in the operator namespace. numberPodsAdvertising uses this list to count replicas advertising the Ingress's Service, so the count cannot be computed. Typical causes are RBAC denials, apiserver errors, or transient network failure between operator and control plane.
Source
Thrown at cmd/k8s-operator/ingress-for-pg.go:849
mak.Set(&secret.Data, fileName, confB)
updated = true
}
if updated {
if err := r.Update(ctx, &secret); err != nil {
return fmt.Errorf("error updating ProxyGroup config Secret: %w", err)
}
}
}
return nil
}
func numberPodsAdvertising(ctx context.Context, cl client.Client, tsNamespace, pgName string, serviceName string) (int, error) {
// Get all state Secrets for this ProxyGroup.
secrets := &corev1.SecretList{}
if err := cl.List(ctx, secrets, client.InNamespace(tsNamespace), client.MatchingLabels(pgSecretLabels(pgName, kubetypes.LabelSecretTypeState))); err != nil {
return 0, fmt.Errorf("failed to list ProxyGroup %q state Secrets: %w", pgName, err)
}
var count int
for _, secret := range secrets.Items {
prefs, ok, err := getDevicePrefs(&secret)
if err != nil {
return 0, fmt.Errorf("error getting node metadata: %w", err)
}
if !ok {
continue
}
if slices.Contains(prefs.AdvertiseServices, serviceName) {
count++
}
}
return count, nil
}View on GitHub (pinned to cfe32b8be6)
Solutions
- Check the wrapped error status: 403 means RBAC — restore the operator's secret list permissions
- kubectl get secrets -n <operator-ns> -l tailscale.com/parent-proxy-group=<pgName> to confirm the selector and namespace are correct
- If transient (5xx/timeout), wait for the automatic requeue before taking further action
- Confirm the operator is watching the namespace where ProxyGroup state Secrets actually live
Defensive patterns
Strategy: retry
Try / catch
if err := cl.List(ctx, secrets, client.InNamespace(ns), client.MatchingLabels(labels)); err != nil {
if apierrors.IsForbidden(err) {
// permanent config problem: surface loudly, do not hot-loop
return 0, fmt.Errorf("RBAC denies listing ProxyGroup state Secrets: %w", err)
}
return 0, fmt.Errorf("failed to list ProxyGroup state Secrets: %w", err)
} Prevention
- Install the operator with its bundled ClusterRole; never hand-trim secret list permissions
- Pin the operator namespace so state Secret selection stays stable across re-installs
- Monitor reconcile_error_total in operator metrics to catch permission drift early
When it happens
Trigger: cl.List(ctx, secrets, client.InNamespace(tsNamespace), client.MatchingLabels(...)) while reconciling an HA Ingress whose ProxyGroup replicas should be counted. Fires on: missing list permission on secrets in tsNamespace; apiserver unavailable; an invalid label key/value in pgSecretLabels (should not happen with current code).
Common situations: Operator installed with a narrowed ClusterRole; operator namespace mismatch after helm re-install; control plane briefly unavailable during upgrade; ProxyGroup never started so labels differ (usually yields empty list, not an error).
Related errors
- failed to list config Secrets: %w
- error updating ProxyGroup config Secret: %w
- failed to create or update Secret %s: %w
- failed to get TLS Secret: %w
- failed to set reissue_authkey in Kubernetes Secret: %w
AI-assisted analysis of tailscale/tailscale@cfe32b8be6 (2026-08-15).
Data as JSON: /api/errors/4dbde3c0161cead7.
Report an issue: GitHub.