derailed/k9s · error

Container %s is not running?

Error message

Container %s is not running?

What it means

The container was found in the pod's status, but render.ToContainerState(cs.State) is not "Running" — it is Waiting (Pending/ImagePullBackOff/CrashLoopBackOff) or Terminated. The operation being attempted (exec, attach, port-forward, log streaming) requires a running container.

Source

Thrown at internal/view/container.go:229

	ShowPortForwards(c, c.GetTable().Path+"|"+path, ports, ann, startFwdCB)

	return nil
}

func checkRunningStatus(co string, ss []v1.ContainerStatus) error {
	var cs *v1.ContainerStatus
	for i := range ss {
		if ss[i].Name == co {
			cs = &ss[i]
			break
		}
	}
	if cs == nil {
		return fmt.Errorf("unable to locate container status for %q", co)
	}

	if render.ToContainerState(cs.State) != "Running" {
		return fmt.Errorf("Container %s is not running?", co)
	}

	return nil
}

func locateContainer(co string, cc []v1.Container) (*v1.Container, error) {
	for i := range cc {
		if cc[i].Name == co {
			return &cc[i], nil
		}
	}
	return nil, fmt.Errorf("unable to locate container named %q", co)
}

func (c *Container) listForwardable(path string) (port.ContainerPortSpecs, map[string]string, bool) {
	po, err := fetchPod(c.App().factory, c.GetTable().Path)
	if err != nil {
		return nil, nil, false

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. Inspect why it is not running: kubectl describe pod <pod> and kubectl logs --previous for events/crash causes.
  2. Fix the underlying cause (image name, registry secret, app crash, probes).
  3. Wait for Running: kubectl wait --for=condition=Ready pod/<pod> --timeout=120s, then retry.
  4. For completed Job containers, accept that exec/attach is impossible; use logs instead.

Example fix

# before: exec immediately
kubectl exec -it pod/demo -c app -- sh

# after: wait for running, then exec
kubectl wait --for=condition=Ready pod/demo --timeout=120s
kubectl exec -it pod/demo -c app -- sh
Defensive patterns

Strategy: validation

Validate before calling

cs, ok := containerStatusNamed(po.Status.ContainerStatuses, co)
if !ok { return fmt.Errorf("no status for %q", co) }
if render.ToContainerState(cs.State) != "Running" {
    return fmt.Errorf("container %s is %s (waiting: %s) — wait for Running", co, render.ToContainerState(cs.State), waitingReason(cs))
}

Type guard

func isContainerRunning(ss []v1.ContainerStatus, name string) bool {
    for i := range ss {
        if ss[i].Name == name { return render.ToContainerState(ss[i].State) == "Running" }
    }
    return false
}

Try / catch

if err := checkRunningStatus(co, ss); err != nil {
    if strings.Contains(err.Error(), "not running") {
    describePodAndShowEvents(po) // guide to root cause: image, crash, probes
    }
}

Prevention

When it happens

Trigger: Exec/attach into a container stuck in ImagePullBackOff or CrashLoopBackOff; a pod still Pending with containers Waiting (ContainerCreating); a container that just Terminated (completed Job pod); racing a restart loop where state flips between checks.

Common situations: Bad image reference or registry auth failure; crash-looping app under debugging; Jobs completing before interaction; probes failing so the container restarts constantly; acting on a pod snapshot taken before first start.

Related errors


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