{"record":{"id":"7518facfc024678c","repo":"slackhq/nebula","slug":"bind-w","errorCode":null,"errorMessage":"bind: %w","messagePattern":"bind: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"udp/udp_rio_windows.go","lineNumber":72,"sourceCode":"type RIOConn struct {\n\tisOpen  atomic.Bool\n\tl       *slog.Logger\n\tsock    windows.Handle\n\trx, tx  ringBuffer\n\trq      winrio.Rq\n\tresults [packetsPerRing]winrio.Result\n}\n\nfunc NewRIOListener(l *slog.Logger, addr netip.Addr, port int) (*RIOConn, error) {\n\tif !winrio.Initialize() {\n\t\treturn nil, errors.New(\"could not initialize winrio\")\n\t}\n\n\tu := &RIOConn{l: l}\n\n\terr := u.bind(l, &windows.SockaddrInet6{Addr: addr.As16(), Port: port})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"bind: %w\", err)\n\t}\n\n\tfor i := 0; i < packetsPerRing; i++ {\n\t\terr = u.insertReceiveRequest()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"init rx ring: %w\", err)\n\t\t}\n\t}\n\n\tu.isOpen.Store(true)\n\treturn u, nil\n}\n\nfunc (u *RIOConn) bind(l *slog.Logger, sa windows.Sockaddr) error {\n\tvar err error\n\tu.sock, err = winrio.Socket(windows.AF_INET6, windows.SOCK_DGRAM, windows.IPPROTO_UDP)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"winrio.Socket error: %w\", err)","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/udp/udp_rio_windows.go#L54-L90","documentation":"NewRIOListener (Windows Registered I/O UDP path) wraps any error from RIOConn.bind — which itself creates the winrio socket, sets socket options, and binds it to the IPv6-mapped address/port. If binding fails, the whole listener is aborted with 'bind: <cause>'.","triggerScenarios":"Calling udp.NewListener on Windows configured for the RIO implementation when the underlying bind (or socket setup inside bind) fails — e.g. port already in use, address not local, or missing privileges.","commonSituations":"Another process holds the UDP port on Windows; listeners.host not assigned to the machine; firewall/antivirus blocking socket bind; RIO unavailable causing winrio.Socket failure surfaced through this wrapper.","solutions":["Inspect the wrapped cause after 'bind:' (use %w unwrapping) to find the real errno (WSAEADDRINUSE, WSAEACCES, etc.)","Free the UDP port or change listeners.port; verify listeners.host is a local address","Run the process with required privileges or adjust Windows Firewall rules","Switch the UDP implementation (config) away from RIO to the standard path if RIO setup is problematic"],"exampleFix":"// before\nnetstat -ano | findstr :4242  # PID 4321 holds it\ntaskkill /PID 4321\n// after (or in config)\nlisteners:\n  port: 4243","handlingStrategy":"try-catch","validationCode":"// pre-check UDP port availability on Windows\nconn, err := net.ListenPacket(\"udp\", fmt.Sprintf(\"%s:%d\", host, port))\nif err != nil { return fmt.Errorf(\"port %d unavailable: %w\", port, err) }\nconn.Close()","typeGuard":null,"tryCatchPattern":"u, err := udp.NewListener(...)\nif err != nil {\n    if strings.Contains(err.Error(), \"bind:\") {\n        // unwrap further (WSAEADDRINUSE etc.) and adjust port/host/privileges\n    }\n    return err\n}","preventionTips":["Verify listeners.host is an assigned local interface address","Check netstat -ano for UDP port conflicts before deploy","Grant required privileges / adjust Windows Firewall rules for the process","Have a config fallback to a different port or non-RIO implementation"],"tags":["udp","windows","bind","rio","address-in-use"],"backgroundTag":"address-already-in-use","analyzedSha":"dd8f660c0ac37903ec4080ca4d3c861ba9342ceb","analyzedAt":"2026-09-03T11:13:55.444Z","contentChangedAt":"2026-09-03T11:13:55.444Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}