{"record":{"id":"fe4f66356dc4ead0","repo":"valyala/fasthttp","slug":"cannot-listen-on-q-w","errorCode":null,"errorMessage":"cannot listen on %q: %w","messagePattern":"cannot listen on %q: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tcplisten/tcplisten.go","lineNumber":133,"sourceCode":"\n\tif cfg.FastOpen {\n\t\tif err = enableFastOpen(fd); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif err = unix.Bind(fd, sa); err != nil {\n\t\treturn fmt.Errorf(\"cannot bind to %q: %w\", addr, err)\n\t}\n\n\tbacklog := cfg.Backlog\n\tif backlog <= 0 {\n\t\tif backlog, err = soMaxConn(); err != nil {\n\t\t\treturn fmt.Errorf(\"cannot determine backlog to pass to listen(2): %w\", err)\n\t\t}\n\t}\n\tif err = unix.Listen(fd, backlog); err != nil {\n\t\treturn fmt.Errorf(\"cannot listen on %q: %w\", addr, err)\n\t}\n\n\treturn nil\n}\n\nfunc getSockaddr(network, addr string) (sa unix.Sockaddr, soType int, err error) {\n\ttcpAddr, err := net.ResolveTCPAddr(network, addr)\n\tif err != nil {\n\t\treturn nil, -1, err\n\t}\n\n\tswitch network {\n\tcase \"tcp4\":\n\t\tvar sa4 unix.SockaddrInet4\n\t\tsa4.Port = tcpAddr.Port\n\t\tcopy(sa4.Addr[:], tcpAddr.IP.To4())\n\t\treturn &sa4, unix.AF_INET, nil\n\tcase \"tcp6\":","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/valyala/fasthttp/blob/c96f600972c6f4a7a30d664257b340ebe9d60124/tcplisten/tcplisten.go#L115-L151","documentation":"After obtaining a bound socket fd and determining the backlog, fdSetup calls unix.Listen(fd, backlog). If the kernel rejects the listen(2) call, the library wraps the syscall error as \"cannot listen on %q\" with the address. This means the socket was bound but could not be transitioned into a listening state.","triggerScenarios":"NewListener on an address where unix.Listen fails on the already-bound fd — typically when the fd is not a valid listening-capable socket, the socket was closed concurrently, or the backlog exceeds kernel limits (backlog overflow EINVAL on some kernels with values > SOMAXCONN caps).","commonSituations":"Passing a custom Backlog larger than the kernel accepts; fd misuse in forked/exec'd processes (SO_REUSEPORT inherited sockets); resource exhaustion in the network stack; calling NewListener twice on the same bound fd.","solutions":["Inspect the wrapped %w error from unix.Listen for the exact errno","Lower cfg.Backlog to a value <= 4096 / kernel somaxconn","Ensure NewListener is called once per socket and the fd is not closed elsewhere","Verify the process has permission to listen on the address (privileges for low ports)"],"exampleFix":"// before\ncfg := tcplisten.Config{Backlog: 1 << 30} // absurd backlog\nln, err := tcplisten.NewListener(cfg, \"tcp\", \":8080\")\n// after\ncfg := tcplisten.Config{Backlog: 4096}\nln, err := tcplisten.NewListener(cfg, \"tcp\", \":8080\")","handlingStrategy":"try-catch","validationCode":"if cfg.Backlog > 1<<16-1 {\n    cfg.Backlog = 1<<16 - 1 // clamp to kernel-safe maximum\n}","typeGuard":null,"tryCatchPattern":"ln, err := tcplisten.NewListener(cfg, network, addr)\nif err != nil && strings.Contains(err.Error(), \"cannot listen on\") {\n    log.Errorf(\"listen(2) failed on %s: %v\", addr, err)\n    return fmt.Errorf(\"listener setup failed for %s: %w\", addr, err)\n}","preventionTips":["Keep Backlog within uint16/uint32 kernel bounds","Call NewListener exactly once per socket address","Run with sufficient privileges for the target port","Monitor the wrapped errno to distinguish resource vs. permission causes"],"tags":["network","linux","tcp","listen-syscall"],"backgroundTag":"listen-syscall-failed","analyzedSha":"c96f600972c6f4a7a30d664257b340ebe9d60124","analyzedAt":"2026-08-31T22:48:28.265Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}