{"record":{"id":"08c6d555dbb37c4b","repo":"GoogleContainerTools/skaffold","slug":"statuscheck-statefulset-fetch-err","errorCode":"STATUSCHECK_STATEFULSET_FETCH_ERR","errorMessage":"could not fetch statefulsets: %w","messagePattern":"could not fetch statefulsets: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/kubernetes/status/status_check.go","lineNumber":196,"sourceCode":"\t\treturn proto.StatusCode_STATUSCHECK_KUBECTL_CLIENT_FETCH_ERR, fmt.Errorf(\"getting Kubernetes client: %w\", err)\n\t}\n\tresources := make([]*resource.Resource, 0)\n\tfor _, n := range *s.namespaces {\n\t\tnewDeployments, err := getDeployments(ctx, client, n, s.labeller, getDeadline(s.deadlineSeconds), s.tolerateFailures)\n\t\tif err != nil {\n\t\t\treturn proto.StatusCode_STATUSCHECK_DEPLOYMENT_FETCH_ERR, fmt.Errorf(\"could not fetch deployments: %w\", err)\n\t\t}\n\t\tfor _, d := range newDeployments {\n\t\t\tif s.seenResources.Contains(d) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tresources = append(resources, d)\n\t\t\ts.seenResources.Add(d)\n\t\t}\n\n\t\tnewStatefulSets, err := getStatefulSets(ctx, client, n, s.labeller, getDeadline(s.deadlineSeconds), s.tolerateFailures)\n\t\tif err != nil {\n\t\t\treturn proto.StatusCode_STATUSCHECK_STATEFULSET_FETCH_ERR, fmt.Errorf(\"could not fetch statefulsets: %w\", err)\n\t\t}\n\t\tfor _, d := range newStatefulSets {\n\t\t\tif s.seenResources.Contains(d) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tresources = append(resources, d)\n\t\t\ts.seenResources.Add(d)\n\t\t}\n\n\t\tnewStandalonePods, err := getStandalonePods(ctx, client, n, s.labeller, getDeadline((s.deadlineSeconds)), s.tolerateFailures)\n\t\tif err != nil {\n\t\t\treturn proto.StatusCode_STATUSCHECK_STANDALONE_PODS_FETCH_ERR, fmt.Errorf(\"could not fetch standalone pods: %w\", err)\n\t\t}\n\t\tfor _, pods := range newStandalonePods {\n\t\t\tif s.seenResources.Contains(pods) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tresources = append(resources, pods)","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/kubernetes/status/status_check.go#L178-L214","documentation":"Same pattern as deployments: statusCheck wraps any error listing StatefulSets with this message and STATUSCHECK_STATEFULSET_FETCH_ERR. It originates from getStatefulSets calling client.AppsV1().StatefulSets(ns).List(...).","triggerScenarios":"client.AppsV1().StatefulSets(ns).List fails per namespace: RBAC denial on statefulsets.apps, missing namespace, unreachable API server, or transport error.","commonSituations":"Cluster where the RBAC role covers deployments but not statefulsets; namespace typo; cluster upgraded/credentials rotated mid-run; private-cluster firewall blocking the control plane.","solutions":["Check 'kubectl auth can-i list statefulsets.apps -n <ns>'","Verify namespace and context, then 'kubectl get statefulsets -n <ns>' directly","Add statefulsets.apps get/list/watch to the RBAC role if denied","Fix kubeconfig/credentials (re-authenticate, e.g. gcloud container clusters get-credentials)","Retry after restoring API server connectivity"],"exampleFix":"// before: role without statefulsets\n//   kubectl create role dev --verb=get,list --resource=deployments.apps\n// after:\n//   kubectl create role dev --verb=get,list,watch --resource=deployments.apps,statefulsets.apps","handlingStrategy":"try-catch","validationCode":"const canList = execSync(`kubectl auth can-i list statefulsets.apps -n ${ns}`).toString().trim();\nif (canList !== 'yes') throw new Error(`RBAC: cannot list statefulsets in ${ns}`);","typeGuard":"function isStatefulSetFetchErr(err) {\n  return err != null && typeof err.message === 'string' && err.message.includes('could not fetch statefulsets');\n}","tryCatchPattern":"try {\n  await statusCheck();\n} catch (err) {\n  if (err.message.includes('could not fetch statefulsets')) {\n    log.error('statefulset list failed:', err.cause ?? err.message);\n  }\n  throw err;\n}","preventionTips":["Include statefulsets.apps in RBAC roles alongside deployments","Verify namespaces exist before status check","Test cluster reachability with a cheap kubectl get before the pipeline's status phase"],"tags":["kubernetes","rbac","statefulset","api-server"],"backgroundTag":"kubernetes-api-list-forbidden","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"}