GoogleContainerTools/skaffold · error
patching resource %q: %w
Error message
patching resource %q: %w
What it means
The cluster-scoped (non-namespaced) branch of updateRuntimeObject patches the resource via Resource(gvr).Patch without a namespace. This error wraps API server rejections or transport failures for that cluster-scoped patch — e.g. Nodes, ClusterRoles, or CRDs being labeled.
Source
Thrown at pkg/skaffold/deploy/label/labels.go:126
if accessor.GetNamespace() != "" {
namespace = accessor.GetNamespace()
} else {
namespace = res.Namespace
}
ns, err := resolveNamespace(namespace, kubeContext)
if err != nil {
return fmt.Errorf("resolving namespace: %w", err)
}
log.Entry(ctx).Debug("Patching", name, "in namespace", ns)
if _, err := client.Resource(gvr).Namespace(ns).Patch(ctx, name, types.StrategicMergePatchType, p, metav1.PatchOptions{}); err != nil {
return fmt.Errorf("patching resource %s/%q: %w", ns, name, err)
}
} else {
log.Entry(ctx).Debug("Patching", name)
if _, err := client.Resource(gvr).Patch(ctx, name, types.StrategicMergePatchType, p, metav1.PatchOptions{}); err != nil {
return fmt.Errorf("patching resource %q: %w", name, err)
}
}
return nil
}
func resolveNamespace(ns, kubeContext string) (string, error) {
if ns != "" {
return ns, nil
}
cfg, err := kubectx.CurrentConfig()
if err != nil {
return "", fmt.Errorf("getting kubeconfig: %w", err)
}
current, present := cfg.Contexts[kubeContext]
if present && current.Namespace != "" {
return current.Namespace, nilView on GitHub (pinned to a1189de023)
Solutions
- Check `kubectl auth can-i patch <cluster-scoped-resource>` and grant a ClusterRole with patch if denied
- Confirm the object exists: `kubectl get <resource> <name>`
- Check connectivity with `kubectl cluster-info` and retry if transient
- Ensure the manifest's apiVersion matches a served cluster-scoped resource
Defensive patterns
Strategy: retry
Validate before calling
allowed, err := authClient.SelfSubjectAccessReviews().Create(ctx,
&authv1.SelfSubjectAccessReview{Spec: authv1.SelfSubjectAccessReviewSpec{
ResourceAttributes: &authv1.ResourceAttributes{Verb: "patch", Resource: resource}}}]) Try / catch
if _, err := client.Resource(gvr).Patch(ctx, name, types.StrategicMergePatchType, p, metav1.PatchOptions{}); err != nil {
if apierrors.IsNotFound(err) { return nil }
if apierrors.IsForbidden(err) { return fmt.Errorf("needs cluster-level patch rights on %s: %w", gvr.Resource, err) }
return retryable(err)
} Prevention
- Bind ClusterRole with patch for cluster-scoped resources in CI
- Verify objects exist with kubectl get before labeling
- Retry transient network errors with backoff
- Confirm apiVersion matches a served cluster-scoped resource
When it happens
Trigger: Patching a cluster-scoped object fails: RBAC denies patch on cluster-scoped resources, object not found, conflict, or API server/network error.
Common situations: CI ServiceAccount without cluster-level patch rights; user lacks cluster-admin for the resource kind; resource removed concurrently; ephemeral cluster connectivity issues.
Related errors
- patching resource %s/%q: %w
- getting pods for namespace %q: %w
- unable to inspect the nodes: %w
- listing pods: %w
- selecting services by label %q: %w
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/17d74b0293a9ca24.
Report an issue: GitHub.