derailed/k9s · error

unable to set image. This pod is managed by %s. Please set t

Error message

unable to set image. This pod is managed by %s. Please set the image on the controller

What it means

Before patching images, SetImages inspects ownerReferences for a controller=true entry. Pods created by Deployments/StatefulSets/DaemonSets/Jobs are managed: any image patch on the pod is reverted by the controller on the next reconcile, so the DAO refuses and names the managing object.

Source

Thrown at internal/dao/pod.go:570

	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,
		n,
		types.StrategicMergePatchType,
		jsonPatch,
		metav1.PatchOptions{},
	)

	return err

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. Set the image on the controlling workload: kubectl set image deployment/<d> <container>=<image> (likewise statefulsets/daemonsets)
  2. For throwaway debugging, patch the controller or attach an ephemeral container instead of patching the pod
  3. If the pod must be truly standalone, recreate it without a controller ownerReference

Example fix

# before
k9s: set image on pod my-deploy-7d9c4f6b5-x2kzv  (rejected)

# after
kubectl set image deployment/my-deploy app=nginx:1.27 -n my-ns
Defensive patterns

Strategy: type-guard

Validate before calling

pod, err := podDAO.GetInstance(fqn)
if err != nil { return err }
if mgr, ok := controllerOf(pod); ok {
    return fmt.Errorf("set image on %s instead", mgr)
}

Type guard

func controllerOf(p *v1.Pod) (string, bool) {
    for _, ref := range p.GetOwnerReferences() {
        if ref.Controller != nil && *ref.Controller {
            return ref.Kind + "/" + ref.Name, true
        }
    }
    return "", false
}

Try / catch

if err := podDAO.SetImages(ctx, path, specs); err != nil {
    if strings.Contains(err.Error(), "managed by") {
        // extract manager from message and redirect the patch to that controller
    }
}

Prevention

When it happens

Trigger: Calling SetImages on any pod whose metadata.ownerReferences contains a controller (manager reported as e.g. replicaset/my-rs).

Common situations: Trying to hot-swap an image on a Deployment-owned pod instead of the Deployment; users hitting set-image on workload-managed pods in k9s; debugging attempts that would be silently undone.

Related errors


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