{"record":{"id":"f82c66d1ada88204","repo":"slackhq/nebula","slug":"init-rx-ring-w","errorCode":null,"errorMessage":"init rx ring: %w","messagePattern":"init rx ring: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"udp/udp_rio_windows.go","lineNumber":78,"sourceCode":"\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)\n\t}\n\n\t// Enable v4 for this socket\n\tsyscall.SetsockoptInt(syscall.Handle(u.sock), syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 0)\n\n\t// Disable reporting of PORT_UNREACHABLE and NET_UNREACHABLE errors from the UDP socket receive call.","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/udp/udp_rio_windows.go#L60-L96","documentation":"After binding, NewRIOListener posts packetsPerBallast... specifically packetsPerRing receive requests into the RIO receive ring via insertReceiveRequest; if any post fails the listener is aborted with 'init rx ring: <cause>'. This means the RIO completion/recv ring could not be initialized.","triggerScenarios":"Calling udp.NewRIOListener (via udp.NewListener on Windows RIO) when winrio.RIOReceive/queue registration fails while filling the receive ring — e.g. RIO buffer/queue exhaustion, invalid memory registration, or RIO disabled by the OS.","commonSituations":"Windows versions where RIO misbehaves; resource limits on registered memory; antivirus/NDIS filter drivers interfering with RIO; misconfigured ring sizing in the udp package options.","solutions":["Check the wrapped cause after 'init rx ring:' for the specific winio/winrio error","Switch the UDP implementation to the standard (non-RIO) Windows path","Reboot/update Windows and NIC drivers if RIO resources appear exhausted","Reduce packetsPerRing / ring sizing if memory registration limits are the cause"],"exampleFix":"// before (config forcing RIO)\nudp:\n  implementation: rio\n// after\nudp:\n  implementation: standard","handlingStrategy":"fallback","validationCode":"// only select RIO when the platform is known to support it\nuseRIO := runtime.GOOS == \"windows\" && windowsRIOAvailable()","typeGuard":null,"tryCatchPattern":"u, err := udp.NewListener(rioCfg)\nif err != nil && strings.Contains(err.Error(), \"init rx ring\") {\n    log.Warn(\"RIO rx ring init failed; falling back to standard UDP\", \"err\", err)\n    u, err = udp.NewListener(stdCfg)\n}","preventionTips":["Keep Windows and NIC drivers updated where RIO is used","Provide a standard-implementation fallback in deployment config","Avoid NDIS filter/AV drivers known to break RIO in production images","Size ring buffers within registered-memory limits"],"tags":["udp","windows","rio","receive-ring","winrio"],"backgroundTag":"rio-ring-init-failed","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"}