derailed/k9s · error

pod must be running. Current status=%v

Error message

pod must be running. Current status=%v

What it means

ensurePodPortFwdAllowed (internal/view/pf_extender.go:125) fetches the pod and rejects the operation unless pod.Status.Phase == v1.PodRunning. The Kubernetes portforward API requires an active sandbox, which only exists once the pod is Running. The message reports the actual phase (Pending, Succeeded, Failed, Unknown).

Source

Thrown at internal/view/pf_extender.go:125

func (p *PortForwardExtender) portForwardContext(ctx context.Context) context.Context {
	if bc := p.App().BenchFile; bc != "" {
		ctx = context.WithValue(ctx, internal.KeyBenchCfg, p.App().BenchFile)
	}

	return context.WithValue(ctx, internal.KeyPath, p.GetTable().GetSelectedItem())
}

// ----------------------------------------------------------------------------
// Helpers...

func ensurePodPortFwdAllowed(factory dao.Factory, podName string) error {
	pod, err := fetchPod(factory, podName)
	if err != nil {
		return err
	}
	if pod.Status.Phase != v1.PodRunning {
		return fmt.Errorf("pod must be running. Current status=%v", pod.Status.Phase)
	}

	return nil
}

func runForward(v ResourceViewer, pf watch.Forwarder, f *portforward.PortForwarder) {
	v.App().factory.AddForwarder(pf)

	v.App().QueueUpdateDraw(func() {
		DismissPortForwards(v, v.App().Content.Pages)
	})

	pf.SetActive(true)
	if err := f.ForwardPorts(); err != nil {
		v.App().Flash().Warnf("PortForward failed for %s: %s. Deleting!", pf.ID(), err)
	}
	v.App().QueueUpdateDraw(func() {
		v.App().factory.DeleteForwarder(pf.ID())

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. Wait for the pod to reach Running (watch 'kubectl get pod <name> -w' until STATUS=Running) and retry
  2. If the pod is Succeeded/Failed (Job), rerun the Job or forward to a pod from an active workload
  3. Check events for scheduling/image problems: 'kubectl describe pod <name>' (ImagePullBackOff, Pending reasons)
  4. For multi-replica workloads, forward from a replica that is Running instead of the one selected

Example fix

// before: port-forward while pod is Pending
// -> pod must be running. Current status=Pending

# after: wait for Running, then retry
kubectl get pod mypod -w   # wait for STATUS=Running
# in k9s: shift+f again
Defensive patterns

Strategy: validation

Validate before calling

// check pod phase before attempting a forward
pod, err := fetchPod(factory, podName)
if err != nil { return err }
if pod.Status.Phase != v1.PodRunning {
    return fmt.Errorf("pod is %s; wait for Running before port-forwarding", pod.Status.Phase)
}

Try / catch

// if calling the k8s portforward API directly, expect SPDY errors on non-running pods and re-check phase
if err := pf.Start(); err != nil {
    if pod, perr := fetchPod(factory, podName); perr == nil && pod.Status.Phase != v1.PodRunning {
        return fmt.Errorf("pod not Running (%s): %w", pod.Status.Phase, err)
    }
    return err
}

Prevention

When it happens

Trigger: Starting a port-forward on a pod that is Pending (still pulling images / scheduling), Succeeded or Failed (Job pods), or Unknown (lost node). Also triggered by forwarding from a Deployment/StatefulSet immediately after creation before the pod transitions to Running.

Common situations: Rollouts in progress: user hits shift+f right after kubectl apply; completed/failed Job pods that still appear in the pod list; CrashLoopBackOff pods whose phase is Running intermittently (this one passes the phase check but fails later); node not ready.

Related errors


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