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, falseView on GitHub (pinned to 2d3ccc6ba2)
Solutions
- Inspect why it is not running: kubectl describe pod <pod> and kubectl logs --previous for events/crash causes.
- Fix the underlying cause (image name, registry secret, app crash, probes).
- Wait for Running: kubectl wait --for=condition=Ready pod/<pod> --timeout=120s, then retry.
- 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
- Gate exec/attach/port-forward UI on container state == Running from live status.
- For crash-looping containers use logs --previous instead of exec.
- After rollout/restart, wait on Ready condition before interacting.
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
- unable to locate container status for %q
- unable to locate container named %q
- user is not authorized to list pod metrics
- namespace not ready
- no matching pods for %v
AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15).
Data as JSON: /api/errors/4b03404f81545a16.
Report an issue: GitHub.