slackhq/nebula · critical
bind: %w
Error message
bind: %w
What it means
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>'.
Source
Thrown at udp/udp_rio_windows.go:72
type RIOConn struct {
isOpen atomic.Bool
l *slog.Logger
sock windows.Handle
rx, tx ringBuffer
rq winrio.Rq
results [packetsPerRing]winrio.Result
}
func NewRIOListener(l *slog.Logger, addr netip.Addr, port int) (*RIOConn, error) {
if !winrio.Initialize() {
return nil, errors.New("could not initialize winrio")
}
u := &RIOConn{l: l}
err := u.bind(l, &windows.SockaddrInet6{Addr: addr.As16(), Port: port})
if err != nil {
return nil, fmt.Errorf("bind: %w", err)
}
for i := 0; i < packetsPerRing; i++ {
err = u.insertReceiveRequest()
if err != nil {
return nil, fmt.Errorf("init rx ring: %w", err)
}
}
u.isOpen.Store(true)
return u, nil
}
func (u *RIOConn) bind(l *slog.Logger, sa windows.Sockaddr) error {
var err error
u.sock, err = winrio.Socket(windows.AF_INET6, windows.SOCK_DGRAM, windows.IPPROTO_UDP)
if err != nil {
return fmt.Errorf("winrio.Socket error: %w", err)View on GitHub (pinned to dd8f660c0a)
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
Example fix
// before netstat -ano | findstr :4242 # PID 4321 holds it taskkill /PID 4321 // after (or in config) listeners: port: 4243
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check UDP port availability on Windows
conn, err := net.ListenPacket("udp", fmt.Sprintf("%s:%d", host, port))
if err != nil { return fmt.Errorf("port %d unavailable: %w", port, err) }
conn.Close() Try / catch
u, err := udp.NewListener(...)
if err != nil {
if strings.Contains(err.Error(), "bind:") {
// unwrap further (WSAEADDRINUSE etc.) and adjust port/host/privileges
}
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- unable to bind to socket: %w
- init rx ring: %w
- winrio.Socket error: %w
- error rx.Open(): %w
- error tx.Open(): %w
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/7518facfc024678c.
Report an issue: GitHub.