tailscale/tailscale · error

error reloading config Secret %q: %v

Error message

error reloading config Secret %q: %v

What it means

Returned when a watched Secret update (Added/Modified with non-nil Data) fails to convert to config: configFromSecret errored while reloading. Wraps either the missing-key error (1197) or a conf.Load parse failure (1183) with %v.

Source

Thrown at cmd/k8s-proxy/internal/config/config.go:240

				if err != nil {
					return fmt.Errorf("failed to re-watch config Secret %q: %w", secretName, err)
				}
				continue
			}

			switch ev.Type {
			case watch.Added, watch.Modified:
				// New config available to load.
				var ok bool
				secret, ok = ev.Object.(*corev1.Secret)
				if !ok {
					return fmt.Errorf("unexpected object type %T in watch event for config Secret %q", ev.Object, secretName)
				}
				if secret == nil || secret.Data == nil {
					continue
				}
				if err := ld.configFromSecret(ctx, secret); err != nil {
					return fmt.Errorf("error reloading config Secret %q: %v", secret.Name, err)
				}
			case watch.Error:
				return fmt.Errorf("error watching config Secret %q: %v", secretName, ev.Object)
			default:
				// Ignore, no action required.
				continue
			}
		}
	}
}

func (ld *configLoader) configFromSecret(ctx context.Context, s *corev1.Secret) error {
	b := s.Data[kubetypes.KubeAPIServerConfigFile]
	if len(b) == 0 {
		return fmt.Errorf("config Secret %q does not contain expected config in key %q", s.Name, kubetypes.KubeAPIServerConfigFile)
	}

	if err := ld.reloadConfig(ctx, b); err != nil {

View on GitHub (pinned to cfe32b8be6)

Solutions

  1. Inspect the new Secret content: kubectl get secret <name> -n <ns> -o jsonpath='{.data.config\.hujson}' | base64 -d and lint it
  2. Restore or fix the expected key with valid content
  3. Restart the proxy pod to reload once fixed
Defensive patterns

Strategy: validation

Validate before calling

if b := newSecret.Data[kubetypes.KubeAPIServerConfigFile]; len(b) == 0 {
	return fmt.Errorf("update rejected: key %q missing", kubetypes.KubeAPIServerConfigFile)
} else if _, err := conf.Load(b); err != nil {
	return fmt.Errorf("update rejected: config invalid: %w", err)
}

Prevention

When it happens

Trigger: The Secret is updated and the event is processed, but the new data lacks the expected key, or the new bytes under that key fail conf.Load. Unlike the initial load, this kills the watch loop after a previously good config was loaded.

Common situations: Operator or user patches the Secret and removes/renames the config key; a config rollout with invalid syntax reaches the proxy; CI writing a new config with a different key name.

Related errors


AI-assisted analysis of tailscale/tailscale@cfe32b8be6 (2026-08-15). Data as JSON: /api/errors/905eeb1e86324e32. Report an issue: GitHub.