{"record":{"id":"7480d8c85e8fdc31","repo":"slackhq/nebula","slug":"could-not-initialize-winrio","errorCode":null,"errorMessage":"could not initialize winrio","messagePattern":"could not initialize winrio","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"udp/udp_rio_windows.go","lineNumber":65,"sourceCode":"\tiocp       windows.Handle\n\tisFull     bool\n\tcq         winrio.Cq\n\tmu         sync.Mutex\n\toverlapped windows.Overlapped\n}\n\ntype 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","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/udp/udp_rio_windows.go#L47-L83","documentation":"NewRIOListener builds a Windows RIO (Registered I/O) based UDP listener. Before use it calls winrio.Initialize(); if the OS refuses to initialize the RIO extension API (unsupported platform/feature), the constructor returns \"could not initialize winrio\" and the fast-path listener cannot be created.","triggerScenarios":"Calling udp.NewListener on Windows (which tries the RIO path via NewRIOListener) on a Windows version/edition lacking Registered I/O support, or in environments (older Windows, some containers/VMs, Wine) where winrio.Initialize returns false.","commonSituations":"Running nebula on Windows 7/Server 2008 R2 without the RIO-capable patch level, inside restricted containers, or under virtualization layers that do not expose RIO; also seen with incompatible winrio syscall bindings on unusual builds.","solutions":["Run on Windows 8/Server 2012 or newer where Registered I/O is supported","Use the non-RIO UDP listener path (build/configure nebula to skip RIO, e.g. a build tag/older release using standard winsock)","Update Windows/VM tooling so the RIO extension API is available to the process"],"exampleFix":"// before\nu, err := udp.NewListener(l, addr, port, true, 2) // attempts RIO on windows\n// after: fall back when RIO init fails\nu, err := udp.NewRIOListener(l, addr, port)\nif err != nil && err.Error() == \"could not initialize winrio\" {\n    u, err = udp.NewUDPListener(l, addr, port)\n}","handlingStrategy":"fallback","validationCode":"func rioSupported() bool {\n    v := windows.RtlGetVersion()\n    return v.MajorVersion > 6 || (v.MajorVersion == 6 && v.MinorVersion >= 2) // Win8/2012+\n}","typeGuard":null,"tryCatchPattern":"u, err := udp.NewRIOListener(l, addr, port)\nif err != nil {\n    if err.Error() == \"could not initialize winrio\" {\n        l.Warn(\"RIO unavailable, falling back to standard UDP listener\")\n        u, err = udp.NewUDPListener(l, addr, port)\n    }\n    if err != nil { return err }\n}","preventionTips":["Run nebula on Windows 8/Server 2012 or newer for RIO support","Test UDP startup on any new VM/container image before rollout","Keep winrio syscall bindings in sync with the target Windows build","Provide a non-RIO fallback path in deployment scripts"],"tags":["nebula","windows","winrio","udp","platform"],"backgroundTag":"windows-api-initialization-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"}