GoogleContainerTools/skaffold · error
initializing deployment watcher: %s
Error message
initializing deployment watcher: %s
What it means
WaitForDeploymentToStabilize starts a Watch on the AppsV1 Deployments API for the target namespace; if that watch request fails it is wrapped as 'initializing deployment watcher: %s'. The failure happens before any stability evaluation, so it reflects API-server access issues (connectivity, auth, RBAC) for the deployments resource.
Source
Thrown at pkg/skaffold/kubernetes/wait.go:143
}
}
return false, nil
})
}
// WaitForDeploymentToStabilize waits until the Deployment has a matching generation/replica count between spec and status.
func WaitForDeploymentToStabilize(ctx context.Context, c kubernetes.Interface, ns, name string, timeout time.Duration) error {
log.Entry(ctx).Infof("Waiting for %s to stabilize", name)
fields := fields.Set{
"metadata.name": name,
"metadata.namespace": ns,
}
w, err := c.AppsV1().Deployments(ns).Watch(ctx, metav1.ListOptions{
FieldSelector: fields.AsSelector().String(),
})
if err != nil {
return fmt.Errorf("initializing deployment watcher: %s", err)
}
return watchUntilTimeout(ctx, timeout, w, func(event *watch.Event) (bool, error) {
if event.Type == watch.Deleted {
return false, apierrs.NewNotFound(schema.GroupResource{Resource: "deployments"}, "")
}
if dp, ok := event.Object.(*appsv1.Deployment); ok {
if dp.Name == name && dp.Namespace == ns &&
dp.Generation <= dp.Status.ObservedGeneration &&
*(dp.Spec.Replicas) == dp.Status.Replicas {
return true, nil
}
glog.Infof("Waiting for deployment %s to stabilize, generation %v observed generation %v spec.replicas %d status.replicas %d",
name, dp.Generation, dp.Status.ObservedGeneration, *(dp.Spec.Replicas), dp.Status.Replicas)
}
return false, nil
})View on GitHub (pinned to a1189de023)
Solutions
- Verify access: `kubectl get deployments -n <ns>` with the same credentials; fix kubeconfig if it fails
- Grant RBAC watch on deployments: add apps/deployments with get,list,watch verbs to the role binding
- Refresh credentials (re-authenticate with the cloud provider, update the token)
- Check API-server reachability/VPN and retry
Example fix
// before (RBAC) resources: ["pods"] // after resources: ["pods", "deployments"]
Defensive patterns
Strategy: retry
Validate before calling
// check deployments watch permission up front
_, err := client.AppsV1().Deployments(ns).List(ctx, metav1.ListOptions{})
if err != nil {
return fmt.Errorf("deployments API not accessible in %s: %w", ns, err)
} Try / catch
err := kubernetes.WaitForDeploymentToStabilize(ctx, client, ns, name, timeout)
if err != nil {
if apierrors.IsForbidden(err) || apierrors.IsUnauthorized(err) {
if rerr := refreshCredentials(ctx); rerr == nil {
err = kubernetes.WaitForDeploymentToStabilize(ctx, client, ns, name, timeout)
}
}
}
return err Prevention
- Include apps/deployments get,list,watch in RBAC roles used by skaffold
- Refresh long-lived tokens before long deploy sessions
- Pin the correct namespace/cluster in kubeconfig for CI runners
- Alert on API-server flakiness in CI networks
When it happens
Trigger: Calling WaitForDeploymentToStabilize when c.AppsV1().Deployments(ns).Watch() errors: API server unreachable, expired credentials, or RBAC denying watch on deployments in namespace ns.
Common situations: Service account limited to pods only (no deployments RBAC) in a hardened cluster; token expiry during a long session; kubeconfig pointing at the wrong namespace/cluster; flaky cluster networking in CI.
Related errors
- initializing pod watcher for %q: %w
- attempting to watch verify job in cluster
- attempting to watch verify pods in cluster
- patching resource %s/%q: %w
- patching resource %q: %w
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/8baf153d09e6c8f1.
Report an issue: GitHub.