derailed/k9s · error

user is not authorized to patch a deployment

Error message

user is not authorized to patch a deployment

What it means

Pod.SetImages authorizes patch on the pod itself (p.gvr = pods) before building the JSON image patch. The message text says "deployment" — legacy wording carried over from the deployment implementation — but the check is patch on core pods in the pod's namespace.

Source

Thrown at internal/dao/pod.go:563

func (p *Pod) GetPodSpec(path string) (*v1.PodSpec, error) {
	pod, err := p.GetInstance(path)
	if err != nil {
		return nil, err
	}
	podSpec := pod.Spec

	return &podSpec, nil
}

// SetImages sets container images.
func (p *Pod) SetImages(ctx context.Context, path string, imageSpecs ImageSpecs) error {
	ns, n := client.Namespaced(path)
	auth, err := p.Client().CanI(ns, p.gvr, n, client.PatchAccess)
	if err != nil {
		return err
	}
	if !auth {
		return fmt.Errorf("user is not authorized to patch a deployment")
	}
	manager, isManaged, err := p.isControlled(path)
	if err != nil {
		return err
	}
	if isManaged {
		return fmt.Errorf("unable to set image. This pod is managed by %s. Please set the image on the controller", manager)
	}
	jsonPatch, err := GetJsonPatch(imageSpecs)
	if err != nil {
		return err
	}
	dial, err := p.Client().Dial()
	if err != nil {
		return err
	}
	_, err = dial.CoreV1().Pods(ns).Patch(
		ctx,

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. Grant patch on pods (not deployments): resources ["pods"] verbs ["patch"]
  2. Verify: kubectl auth can-i patch pods -n <ns>
  3. Read the message knowing 'deployment' is inaccurate — this code path patches core v1 pods

Example fix

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-image-patcher
  namespace: default
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "patch"]
Defensive patterns

Strategy: validation

Validate before calling

ok, err := client.CanI(ns, client.PodGVR, podName, client.PatchAccess)
if err != nil { return err }
if !ok { return fmt.Errorf("patch on pods denied in %s", ns) }

Try / catch

if err := podDAO.SetImages(ctx, path, specs); err != nil {
    if strings.Contains(err.Error(), "not authorized to patch") {
        // RBAC gap on pods (ignore the word 'deployment' in the message)
    }
}

Prevention

When it happens

Trigger: CanI(ns, pods, <pod>, patch) false — the user can view pods but lacks the patch verb on them.

Common situations: View-only users attempting set-image on a pod in k9s; environments where patch is deliberately withheld; operators fixing the wrong RBAC resource because the message says deployment.

Related errors


AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15). Data as JSON: /api/errors/e2516148404bac49. Report an issue: GitHub.