{"record":{"id":"5259a9d5f4a0af45","repo":"derailed/k9s","slug":"port-forward-is-already-active-on-pod-s","errorCode":null,"errorMessage":"port-forward is already active on pod %s","messagePattern":"port-forward is already active on pod (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/view/pf_extender.go","lineNumber":156,"sourceCode":"\tpf.SetActive(true)\n\tif err := f.ForwardPorts(); err != nil {\n\t\tv.App().Flash().Warnf(\"PortForward failed for %s: %s. Deleting!\", pf.ID(), err)\n\t}\n\tv.App().QueueUpdateDraw(func() {\n\t\tv.App().factory.DeleteForwarder(pf.ID())\n\t\tpf.SetActive(false)\n\t})\n}\n\nfunc startFwdCB(v ResourceViewer, path string, pts port.PortTunnels) error {\n\tif err := pts.CheckAvailable(context.Background()); err != nil {\n\t\treturn err\n\t}\n\n\ttt := make([]string, 0, len(pts))\n\tfor _, pt := range pts {\n\t\tif _, ok := v.App().factory.ForwarderFor(dao.PortForwardID(path, pt.Container, pt.PortMap())); ok {\n\t\t\treturn fmt.Errorf(\"port-forward is already active on pod %s\", path)\n\t\t}\n\t\tpf := dao.NewPortForwarder(v.App().factory)\n\t\tfwd, err := pf.Start(path, pt)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tslog.Debug(\">>> Starting port forward\",\n\t\t\tslogs.PFID, pf.ID(),\n\t\t\tslogs.PFTunnel, pt,\n\t\t)\n\t\tgo runForward(v, pf, fwd)\n\t\ttt = append(tt, pt.LocalPort)\n\t}\n\tif len(tt) == 1 {\n\t\tv.App().Flash().Infof(\"PortForward activated %s\", tt[0])\n\t\treturn nil\n\t}\n\tv.App().Flash().Infof(\"PortForwards activated %s\", strings.Join(tt, \",\"))","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/derailed/k9s/blob/2d3ccc6ba2ce98c3781bfc441bb3e884f072774f/internal/view/pf_extender.go#L138-L174","documentation":"startFwdCB (internal/view/pf_extender.go:156) checks the factory's active forwarder registry keyed by dao.PortForwardID(path, container, PortMap()) before starting each tunnel. If a forwarder is already registered for the same pod path + container + container/local port mapping, it refuses to start a duplicate and reports the pod path.","triggerScenarios":"Opening the port-forward dialog on the same pod twice and re-entering an identical container::port -> local port mapping; forwarding again after switching away from the portforwards view without first stopping the existing tunnel.","commonSituations":"Users forget an earlier tunnel is still live; tunnel was started in a different k9s session/tab still running; the local port mysteriously busy because the existing forwarder already binds it.","solutions":["Open the :pf / portforwards view and stop the existing tunnel, then start the new one","Reuse the existing tunnel instead of creating a duplicate — just curl the already-forwarded local port","Enter a different local port in the dialog so PortForwardID differs","If the tunnel belongs to a stale k9s session, exit that session (or kill the kubectl port-forward process) and retry"],"exampleFix":"// before: start same mapping twice\n// Container Port: web::8080  Local Port: 8080  (already active)\n// -> port-forward is already active on pod ns1/mypod\n\n# after: stop it first, or map a new local port\n# in k9s: :pf -> select -> <delete>   OR\n# Container Port: web::8080  Local Port: 8081","handlingStrategy":"validation","validationCode":"// check for an existing forwarder before starting\nfor _, pt := range pts {\n    if _, ok := factory.ForwarderFor(dao.PortForwardID(path, pt.Container, pt.PortMap())); ok {\n        return fmt.Errorf(\"tunnel for %s/%s already exists; stop it or pick another local port\", path, pt.Container)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Review the :pf (portforwards) view before creating new tunnels","Prefer distinct local ports per tunnel so PortForwardID never collides","Exit k9s cleanly so forwarders are torn down instead of lingering"],"tags":["k9s","port-forward","duplicate","tunnel","validation"],"backgroundTag":null,"analyzedSha":"2d3ccc6ba2ce98c3781bfc441bb3e884f072774f","analyzedAt":"2026-08-15T16:09:14.432Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}