{"record":{"id":"1dc65df0a40947f3","repo":"GoogleContainerTools/skaffold","slug":"initializing-pod-watcher-s","errorCode":null,"errorMessage":"initializing pod watcher: %s","messagePattern":"initializing pod watcher: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/kubernetes/wait.go","lineNumber":68,"sourceCode":"\t\tcase event := <-w.ResultChan():\n\t\t\tdone, err := condition(&event)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif done {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n}\n\n// WaitForPodSucceeded waits until the Pod status is Succeeded.\nfunc WaitForPodSucceeded(ctx context.Context, pods corev1.PodInterface, podName string, timeout time.Duration) error {\n\tlog.Entry(ctx).Infof(\"Waiting for %s to be complete\", podName)\n\n\tw, err := newPodsWatcher(ctx, pods)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"initializing pod watcher: %s\", err)\n\t}\n\tdefer w.Stop()\n\n\treturn watchUntilTimeout(ctx, timeout, w, isPodSucceeded(podName))\n}\n\nfunc isPodSucceeded(podName string) func(event *watch.Event) (bool, error) {\n\treturn func(event *watch.Event) (bool, error) {\n\t\tif event.Object == nil {\n\t\t\treturn false, nil\n\t\t}\n\t\tpod, isPod := event.Object.(*v1.Pod)\n\t\tif !isPod {\n\t\t\treturn false, nil\n\t\t}\n\t\tif pod.Name != podName {\n\t\t\treturn false, nil\n\t\t}","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/kubernetes/wait.go#L50-L86","documentation":"WaitForPodSucceeded sets up a pod watcher via newPodsWatcher before waiting for the pod to reach Succeeded. If creating that watcher (a List+Watch against the pods API) fails, the error is wrapped as 'initializing pod watcher: %s'. It almost always reflects a Kubernetes API connectivity, auth, or namespace problem, not anything about the pod itself.","triggerScenarios":"Calling WaitForPodSucceeded with a corev1.PodInterface whose underlying client cannot reach the API server: invalid kubecontext, expired token, network failure, or nonexistent namespace cause the initial List/Watch to error.","commonSituations":"Wrong kubeconfig / KUBECONFIG pointing at a dead cluster; OIDC token expired; VPN disconnected; namespace typo so the List call returns NotFound.","solutions":["Verify cluster connectivity: `kubectl --context <ctx> get pods -n <ns>` with the same context skaffold uses","Check/refresh credentials (`kubectl auth whoami`, re-login to your cloud provider, update kubeconfig tokens)","Confirm the namespace exists and is spelled correctly","Check network/VPN to the API server, then retry the wait"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// verify API access with the same client config before waiting\n_, err := pods.List(ctx, metav1.ListOptions{})\nif err != nil {\n    return fmt.Errorf(\"cannot access pods API, watcher init would fail: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"err := kubernetes.WaitForPodSucceeded(ctx, pods, podName, timeout)\nif err != nil {\n    if apierrors.IsUnauthorized(err) || apierrors.IsForbidden(err) || isConnErr(err) {\n        if rerr := refreshCredentials(ctx); rerr == nil {\n            err = kubernetes.WaitForPodSucceeded(ctx, pods, podName, timeout)\n        }\n    }\n}\nreturn err","preventionTips":["Validate the kube-context with `kubectl get pods -n <ns>` before long waits","Keep tokens refreshed for OIDC/cloud auth setups","Confirm the namespace exists before watching pods in it","Check VPN/network connectivity in remote-cluster scenarios"],"tags":["kubernetes","watch","api-client"],"backgroundTag":"kubernetes-api-unreachable","analyzedSha":"a1189de023efc32d4b8e11f395acc678aa555011","analyzedAt":"2026-09-05T12:09:27.064Z","contentChangedAt":"2026-09-05T12:09:27.064Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}