tailscale/tailscale · error
failed to check if any Pods are configured: %w
Error message
failed to check if any Pods are configured: %w
What it means
Thrown by HAIngressReconciler.maybeProvision when numberPodsAdvertising fails: it lists the ProxyGroup's state Secrets (label-selected on ProxyGroup name and secret type state) and parses device prefs from each. The wrapped error is either the Secret list call failing (RBAC/apiserver) or getDevicePrefs choking on a state Secret whose prefs bytes do not unmarshal ('error getting node metadata'). The count is used to decide whether Ingress status may advertise the service.
Source
Thrown at cmd/k8s-operator/ingress-for-pg.go:380
if err := tsClient.VIPServices().CreateOrUpdate(ctx, tsSvc); err != nil {
return false, fmt.Errorf("error creating Tailscale Service: %w", err)
}
}
// 5. Update tailscaled's AdvertiseServices config, which should add the Tailscale Service
// IPs to the ProxyGroup Pods' AllowedIPs in the next netmap update if approved.
mode := serviceAdvertisementHTTPS
if isHTTPEndpointEnabled(ing) || isHTTPRedirectEnabled(ing) {
mode = serviceAdvertisementHTTPAndHTTPS
}
if err = r.maybeUpdateAdvertiseServicesConfig(ctx, serviceName, mode, pg); err != nil {
return false, fmt.Errorf("failed to update tailscaled config: %w", err)
}
// 6. Update Ingress status if ProxyGroup Pods are ready.
count, err := numberPodsAdvertising(ctx, r.Client, r.tsNamespace, pg.Name, serviceName.String())
if err != nil {
return false, fmt.Errorf("failed to check if any Pods are configured: %w", err)
}
oldStatus := ing.Status.DeepCopy()
switch count {
case 0:
ing.Status.LoadBalancer.Ingress = nil
default:
var ports []networkingv1.IngressPortStatus
hasCerts, err := hasCerts(ctx, r.Client, r.tsNamespace, serviceName, pg)
if err != nil {
return false, fmt.Errorf("error checking TLS credentials provisioned for Ingress: %w", err)
}
// If TLS certs have not been issued (yet), do not set port 443.
if hasCerts {
ports = append(ports, networkingv1.IngressPortStatus{
Protocol: "TCP",
Port: 443,View on GitHub (pinned to cfe32b8be6)
Solutions
- Read the wrapped error: 'error getting node metadata' means a corrupt state Secret; inspect the ProxyGroup's state Secrets (kubectl get secrets -n <operator-ns> -l tailscale.com/parent=<pg>) and delete the corrupt/orphaned one so the pod regenerates it.
- 'forbidden'/apiserver errors: reapply RBAC or wait out the transient; the reconcile backoff retries.
- Ensure ProxyGroup Pods are healthy so they rewrite valid state Secrets.
Defensive patterns
Strategy: retry
Type guard
func isCorruptStateSecretErr(err error) bool {
return err != nil && strings.Contains(err.Error(), "node metadata")
} Try / catch
count, err := numberPodsAdvertising(ctx, r.Client, r.tsNamespace, pg.Name, serviceName.String())
if err != nil {
if isCorruptStateSecretErr(err) {
logger.Error("corrupt ProxyGroup state Secret; regenerate it before retrying")
}
return ctrl.Result{}, fmt.Errorf("failed to check if any Pods are configured: %w", err)
} Prevention
- Let the operator own ProxyGroup state Secrets end to end.
- When scaling ProxyGroup replicas, rely on the operator to retire old Secrets.
- Monitor ProxyGroup Pod health; unhealthy pods leave stale state.
When it happens
Trigger: List of state Secrets in the operator namespace denied or failing; a state Secret written partially, hand-edited, or left by a different operator version so prefs do not unmarshal; ctx cancelled while listing.
Common situations: ProxyGroup replica scaled up/down leaving stale Secrets; state Secret corrupted after a pod crash mid-write; restrictive admission/OPA blocking list; apiserver throttling.
Related errors
- error checking TLS credentials provisioned for Ingress: %w
- error checking TLS credentials provisioned for service %q: %
- error unmarshalling previous config: %w
- error unmarshalling previous config: %w
- failed to update tailscaled config: %w
AI-assisted analysis of tailscale/tailscale@cfe32b8be6 (2026-08-15).
Data as JSON: /api/errors/51d0227e84c90b7e.
Report an issue: GitHub.