GoogleContainerTools/skaffold · error
could not fetch deployments: %w
Error message
could not fetch deployments: %w
What it means
getDeployments wraps any error from listing Deployments (client.AppsV1().Deployments(ns).List with the run-id label selector) with 'could not fetch deployments'. statusCheck converts it to STATUSCHECK_DEPLOYMENT_FETCH_ERR. The wrapped cause is the raw Kubernetes client error (network, RBAC, timeout).
Source
Thrown at pkg/skaffold/kubernetes/status/status_check.go:348
for _, r := range uRes {
resName := r.GroupVersionKind().String()
if r.GetName() != "" {
resName = fmt.Sprintf("%s, Name=%s", resName, r.GetName())
}
pd := diag.New([]string{ns}).
WithValidators([]validator.Validator{validator.NewCustomValidator(client, dynClient, r.GroupVersionKind())})
result = append(result, resource.NewResource(resName, resource.ResourceTypes.CustomResource, ns, deadlineDuration, tolerateFailures).WithValidator(pd))
}
return result, nil
}
func getDeployments(ctx context.Context, client kubernetes.Interface, ns string, l *label.DefaultLabeller, deadlineDuration time.Duration, tolerateFailures bool) ([]*resource.Resource, error) {
deps, err := client.AppsV1().Deployments(ns).List(ctx, metav1.ListOptions{
LabelSelector: l.RunIDSelector(),
})
if err != nil {
return nil, fmt.Errorf("could not fetch deployments: %w", err)
}
resources := make([]*resource.Resource, len(deps.Items))
for i, d := range deps.Items {
var deadline time.Duration
if d.Spec.ProgressDeadlineSeconds == nil || *d.Spec.ProgressDeadlineSeconds == kubernetesMaxDeadline {
deadline = deadlineDuration
} else {
deadline = time.Duration(*d.Spec.ProgressDeadlineSeconds) * time.Second
}
pd := diag.New([]string{d.Namespace}).
WithLabel(label.RunIDLabel, l.Labels()[label.RunIDLabel]).
WithValidators([]validator.Validator{validator.NewPodValidator(client, validator.NewDeploymentPodsSelector(client, d))})
for k, v := range d.Spec.Template.Labels {
pd = pd.WithLabel(k, v)
}View on GitHub (pinned to a1189de023)
Solutions
- Reproduce the raw call: 'kubectl get deployments -n <ns> -l <run-id-selector>' and read the wrapped error
- Fix connectivity/credentials: refresh kubeconfig (e.g. gcloud container clusters get-credentials) and re-authenticate
- Fix RBAC if 403: grant get/list/watch on deployments.apps in the namespace
- Verify the namespace exists and the context matches the deployed cluster
- Increase statusCheck deadline or retry once the API server is responsive
Example fix
// before: stale CI kubeconfig pointing at old cluster // kubectl config use-context old-cluster // after: // gcloud container clusters get-credentials my-cluster --region us-central1 // kubectl config use-context my-cluster
Defensive patterns
Strategy: retry
Validate before calling
const ctxOk = execSync('kubectl config current-context').toString().trim();
const nsOk = execSync(`kubectl get ns ${ns} --request-timeout=10s`).toString();
const canList = execSync(`kubectl auth can-i list deployments.apps -n ${ns}`).toString().trim();
if (canList !== 'yes') throw new Error(`RBAC: cannot list deployments in ${ns} (ctx=${ctxOk})`); Type guard
function isDeploymentFetchErr(err) {
return err != null && typeof err.message === 'string' && err.message.includes('could not fetch deployments');
} Try / catch
for (let attempt = 0; attempt < 3; attempt++) {
try { await statusCheck(); break; }
catch (err) {
if (isDeploymentFetchErr(err) && /timeout|connection refused|connection reset/i.test(err.message) && attempt < 2) {
await sleep(2000 * (attempt + 1));
continue;
}
throw err;
}
} Prevention
- Refresh kubeconfig/credentials at the start of CI jobs
- Grant deployments.apps get/list/watch in every status-checked namespace
- Add deadline headroom via statusCheck.deadlineSeconds
- Retry transient network errors with exponential backoff
- Confirm the context matches the deployed cluster before status check
When it happens
Trigger: Deployments List call fails for a namespace: connection refused/timeout to API server, 403 on list deployments.apps, nonexistent namespace, context pointing to wrong cluster, or context deadline exceeded before getDeadline.
Common situations: kubeconfig switched to a cluster without the deployed app; CI runner losing network to the control plane; RBAC roles missing deployments.apps; expired cloud credentials; namespace deleted mid-run.
Related errors
- STATUSCHECK_DEPLOYMENT_FETCH_ERR
- patching resource %s/%q: %w
- getting server resources for group version: %w
- getting pods for namespace %q: %w
- listing pods: %w
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/e1ac1007331e70b5.
Report an issue: GitHub.