{"record":{"id":"4b52050c7c754564","repo":"derailed/k9s","slug":"unable-to-forward-port-because-pod-is-not-running","errorCode":null,"errorMessage":"unable to forward port because pod is not running. Current status=%v","messagePattern":"unable to forward port because pod is not running\\. Current status=(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/dao/port_forwarder.go","lineNumber":141,"sourceCode":"\n\tns, n := client.Namespaced(path)\n\tauth, err := p.Client().CanI(ns, client.PodGVR, n, client.GetAccess)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif !auth {\n\t\treturn nil, fmt.Errorf(\"user is not authorized to get pods\")\n\t}\n\n\tpodName := strings.Split(n, \"|\")[0]\n\tvar res Pod\n\tres.Init(p, client.PodGVR)\n\tpod, err := res.GetInstance(client.FQN(ns, podName))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif pod.Status.Phase != v1.PodRunning {\n\t\treturn nil, fmt.Errorf(\"unable to forward port because pod is not running. Current status=%v\", pod.Status.Phase)\n\t}\n\n\tauth, err = p.Client().CanI(ns, client.PodGVR.WithSubResource(\"portforward\"), \"\", []string{client.CreateVerb})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif !auth {\n\t\treturn nil, fmt.Errorf(\"user is not authorized to update portforward\")\n\t}\n\n\tcfg, err := p.Client().RestConfig()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcfg.GroupVersion = &schema.GroupVersion{Group: \"\", Version: \"v1\"}\n\tcfg.APIPath = \"/api\"\n\tcodec, _ := codec()\n\tcfg.NegotiatedSerializer = codec.WithoutConversion()","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/derailed/k9s/blob/2d3ccc6ba2ce98c3781bfc441bb3e884f072774f/internal/dao/port_forwarder.go#L123-L159","documentation":"Start rejects the session unless the target pod's status.phase is Running. Pending, Succeeded, Failed, or Unknown pods cannot serve a tunnel, so the DAO fails fast and includes the observed phase in the message.","triggerScenarios":"Forwarding while the pod is Pending (image pull, scheduling, init containers), Succeeded/Failed (completed Job pods), or Unknown (node unreachable).","commonSituations":"Forwarding immediately after a rollout before readiness; forwarding to one-shot Job pods that already finished; node NotReady leaving pods in Unknown.","solutions":["Wait for readiness: kubectl wait --for=condition=ready pod/<name> --timeout=90s","Diagnose why it is not Running: kubectl describe pod <name> (events, init containers, probes)","For completed Job pods, run a new pod instead of forwarding to the finished one"],"exampleFix":"// before\npf, err := pfMgr.Start(path, tunnel) // fails on Pending pod\n\n// after\npod, _ := podDAO.GetInstance(fqn)\nif pod == nil || pod.Status.Phase != v1.PodRunning {\n    return fmt.Errorf(\"wait for pod %q to be Running before forwarding (phase=%v)\", fqn, pod.Status.Phase)\n}\npf, err := pfMgr.Start(path, tunnel)","handlingStrategy":"validation","validationCode":"var res dao.Pod\nres.Init(client, client.PodGVR)\npod, err := res.GetInstance(fqn)\nif err != nil { return err }\nif pod.Status.Phase != v1.PodRunning {\n    return fmt.Errorf(\"pod phase %s; wait for Running\", pod.Status.Phase)\n}","typeGuard":"func isRunnable(p *v1.Pod) bool {\n    return p != nil && p.Status.Phase == v1.PodRunning\n}","tryCatchPattern":"if _, err := pf.Start(path, tunnel); err != nil {\n    if strings.Contains(err.Error(), \"pod is not running\") {\n        // wait for ready condition, then retry Start once\n    }\n}","preventionTips":["Gate forwards on readiness conditions, not just on the pod existing","For Job pods, check status.phase != Succeeded before offering forward","Retrigger forwards after rollout events instead of keeping stale tunnels"],"tags":["kubernetes","port-forward","pod-status"],"backgroundTag":null,"analyzedSha":"2d3ccc6ba2ce98c3781bfc441bb3e884f072774f","analyzedAt":"2026-08-15T16:09:14.432Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}