{"record":{"id":"45013f0be19e72f6","repo":"ahmetb/kubectx","slug":"failed-to-listen-w","errorCode":null,"errorMessage":"failed to listen: %w","messagePattern":"failed to listen: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/proxy/readonly.go","lineNumber":85,"sourceCode":"\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to load kubeconfig: %w\", err)\n\t}\n\n\ttargetURL, err := url.Parse(restCfg.Host)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse server URL %q: %w\", restCfg.Host, err)\n\t}\n\n\ttransport, err := rest.TransportFor(restCfg)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create transport: %w\", err)\n\t}\n\n\thandler := NewHandler(targetURL, transport)\n\n\tlistener, err := net.Listen(\"tcp\", \"127.0.0.1:0\")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to listen: %w\", err)\n\t}\n\n\tsrv := &http.Server{Handler: handler}\n\tgo srv.Serve(listener)\n\n\tdebugLog.Printf(\"started on %s, proxying to %s\", listener.Addr(), targetURL)\n\n\treturn &ReadonlyProxy{\n\t\tserver:   srv,\n\t\tlistener: listener,\n\t}, nil\n}\n\n// Addr returns the listener address (e.g. \"127.0.0.1:54321\").\nfunc (p *ReadonlyProxy) Addr() string {\n\treturn p.listener.Addr().String()\n}\n","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/ahmetb/kubectx/blob/12ad6fb22e8c546ee2b54e7de38aa51c906832f7/internal/proxy/readonly.go#L67-L103","documentation":"This error is returned by proxy.Start when net.Listen(\"tcp\", \"127.0.0.1:0\") cannot open a local TCP listener. The library binds to an OS-assigned loopback port to serve the readonly reverse proxy, so failure means the process could not bind any local socket at all, not a port conflict on a specific port. The underlying net.OpError/OS error (e.g. 'too many open files', 'address family not supported') is wrapped via %w.","triggerScenarios":"net.Listen fails when the process has exhausted its file-descriptor limit (EMFILE), the loopback interface is unavailable (lo interface down, no IPv4 support in restricted containers/network namespaces), a mandatory sandbox seccomp/AppArmor policy blocks socket creation, or the system is out of memory for socket buffers.","commonSituations":"Running kubectx readonly mode inside a hardened container or CI sandbox with no loopback networking or low RLIMIT_NOFILE; long-running shells that leaked thousands of fds; minimal distroless images without loopback configured; corporate endpoint-protection software blocking socket creation.","solutions":["Check fd exhaustion with `ulimit -n` and `lsof -p $$`; raise the limit (`ulimit -n 10240`) or close leaked descriptors/connections","Verify loopback is up and usable: `ip addr show lo` / `ping -c1 127.0.0.1`, and bring it up (`ip link set lo up`) if down","If in a container/sandbox, confirm the runtime allows AF_INET socket creation and loopback networking (docker run without network restrictions, adjust seccomp/AppArmor profiles)","Run `KUBECTX_DEBUG=1` and read the wrapped OS error text to pinpoint EMFILE vs EADDRNOTAVAIL vs permission denied","As a workaround, run kubectx outside the restricted environment (host shell) since readonly mode requires a local proxy"],"exampleFix":"// before (shell with low fd limit)\n$ ulimit -n\n64\n// after\n$ ulimit -n 10240\n$ kubectx -r <ctx>","handlingStrategy":"try-catch","validationCode":"// Go: check loopback binding capability before calling proxy.Start\nfunc canBindLoopback() error {\n\tl, err := net.Listen(\"tcp\", \"127.0.0.1:0\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"no loopback TCP available: %w\", err)\n\t}\n\tl.Close()\n\treturn nil\n}\n// also sanity-check fd headroom\nfunc fdHeadroom() error {\n\tvar lim syscall.Rlimit\n\tif err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &lim); err != nil {\n\t\treturn err\n\t}\n\tif lim.Cur < 256 {\n\t\treturn fmt.Errorf(\"RLIMIT_NOFILE too low: %d\", lim.Cur)\n\t}\n\treturn nil\n}","typeGuard":"func isBindError(err error) bool {\n\tvar opErr *net.OpError\n\tif errors.As(err, &opErr) {\n\t\treturn opErr.Op == \"listen\"\n\t}\n\treturn strings.Contains(err.Error(), \"failed to listen\")\n}","tryCatchPattern":"p, err := proxy.Start(cfg)\nif err != nil {\n\tif isBindError(err) {\n\t\tvar sysErr *os.SyscallError\n\t\tif errors.As(err, &sysErr) && errors.Is(sysErr, syscall.EMFILE) {\n\t\t\treturn fmt.Errorf(\"file descriptor limit exhausted; raise ulimit -n\")\n\t\t}\n\t\treturn fmt.Errorf(\"cannot bind loopback (sandbox/no lo interface?): %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Raise RLIMIT_NOFILE for long-running shells and CI jobs before running tools that open sockets","Verify the loopback interface is up (ip link set lo up) in containers and chroots","Use container runtimes/network namespaces that permit AF_INET socket creation; review seccomp/AppArmor profiles","Close leaked connections/files in the host process to preserve fd headroom","Prefer running kubectx readonly mode in a normal user shell rather than minimal/sandboxed environments"],"tags":["go","network","tcp","listen","bind"],"backgroundTag":"address-bind-failure","analyzedSha":"12ad6fb22e8c546ee2b54e7de38aa51c906832f7","analyzedAt":"2026-09-02T12:23:10.107Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T16:17:10.729Z"}