{"record":{"id":"905eeb1e86324e32","repo":"tailscale/tailscale","slug":"error-reloading-config-secret-q-v","errorCode":null,"errorMessage":"error reloading config Secret %q: %v","messagePattern":"error reloading config Secret %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/k8s-proxy/internal/config/config.go","lineNumber":240,"sourceCode":"\t\t\t\tif err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"failed to re-watch config Secret %q: %w\", secretName, err)\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tswitch ev.Type {\n\t\t\tcase watch.Added, watch.Modified:\n\t\t\t\t// New config available to load.\n\t\t\t\tvar ok bool\n\t\t\t\tsecret, ok = ev.Object.(*corev1.Secret)\n\t\t\t\tif !ok {\n\t\t\t\t\treturn fmt.Errorf(\"unexpected object type %T in watch event for config Secret %q\", ev.Object, secretName)\n\t\t\t\t}\n\t\t\t\tif secret == nil || secret.Data == nil {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif err := ld.configFromSecret(ctx, secret); err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"error reloading config Secret %q: %v\", secret.Name, err)\n\t\t\t\t}\n\t\t\tcase watch.Error:\n\t\t\t\treturn fmt.Errorf(\"error watching config Secret %q: %v\", secretName, ev.Object)\n\t\t\tdefault:\n\t\t\t\t// Ignore, no action required.\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (ld *configLoader) configFromSecret(ctx context.Context, s *corev1.Secret) error {\n\tb := s.Data[kubetypes.KubeAPIServerConfigFile]\n\tif len(b) == 0 {\n\t\treturn fmt.Errorf(\"config Secret %q does not contain expected config in key %q\", s.Name, kubetypes.KubeAPIServerConfigFile)\n\t}\n\n\tif err := ld.reloadConfig(ctx, b); err != nil {","sourceCodeStart":222,"sourceCodeEnd":258,"githubUrl":"https://github.com/tailscale/tailscale/blob/cfe32b8be6a33f8e24fbc369cbfbf7c729d9e042/cmd/k8s-proxy/internal/config/config.go#L222-L258","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect the new Secret content: kubectl get secret <name> -n <ns> -o jsonpath='{.data.config\\.hujson}' | base64 -d and lint it","Restore or fix the expected key with valid content","Restart the proxy pod to reload once fixed"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if b := newSecret.Data[kubetypes.KubeAPIServerConfigFile]; len(b) == 0 {\n\treturn fmt.Errorf(\"update rejected: key %q missing\", kubetypes.KubeAPIServerConfigFile)\n} else if _, err := conf.Load(b); err != nil {\n\treturn fmt.Errorf(\"update rejected: config invalid: %w\", err)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run every Secret config update through a validating pipeline (lint then patch)","Never rename the config key during Secret migrations; migrate additively","Canary config changes on a test proxy before applying cluster-wide"],"tags":["kubernetes","secrets","config","parsing"],"backgroundTag":null,"analyzedSha":"cfe32b8be6a33f8e24fbc369cbfbf7c729d9e042","analyzedAt":"2026-08-15T19:58:31.583Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}