{"record":{"id":"f3bd5280859384ae","repo":"slackhq/nebula","slug":"failed-to-write-route-routemessage-to-socket-w","errorCode":null,"errorMessage":"failed to write route.RouteMessage to socket: %w","messagePattern":"failed to write route\\.RouteMessage to socket: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"overlay/tun_darwin.go","lineNumber":457,"sourceCode":"\t\t\tunix.RTAX_NETMASK: &netroute.Inet4Addr{IP: prefixToMask(prefix).As4()},\n\t\t\tunix.RTAX_GATEWAY: gateway,\n\t\t}\n\t} else {\n\t\troute.Addrs = []netroute.Addr{\n\t\t\tunix.RTAX_DST:     &netroute.Inet6Addr{IP: prefix.Masked().Addr().As16()},\n\t\t\tunix.RTAX_NETMASK: &netroute.Inet6Addr{IP: prefixToMask(prefix).As16()},\n\t\t\tunix.RTAX_GATEWAY: gateway,\n\t\t}\n\t}\n\n\tdata, err := route.Marshal()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create route.RouteMessage: %w\", err)\n\t}\n\n\t_, err = unix.Write(sock, data[:])\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to write route.RouteMessage to socket: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc delRoute(prefix netip.Prefix, gateway netroute.Addr) error {\n\tsock, err := unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, unix.AF_UNSPEC)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to create AF_ROUTE socket: %v\", err)\n\t}\n\tdefer unix.Close(sock)\n\n\troute := netroute.RouteMessage{\n\t\tVersion: unix.RTM_VERSION,\n\t\tType:    unix.RTM_DELETE,\n\t\tSeq:     1,\n\t}\n","sourceCodeStart":439,"sourceCodeEnd":475,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/overlay/tun_darwin.go#L439-L475","documentation":"After successfully marshaling an RTM_ADD route message, addRoute() writes it to the AF_ROUTE raw socket via unix.Write. This error wraps the errno when the kernel rejects the write, meaning the route addition message was not accepted for transmission to the routing table.","triggerScenarios":"Called from activate4() or addRoutes(); unix.Write on the routing socket fails, commonly with ENOBUFS (kernel route table buffer exhaustion) or EPERM (insufficient privileges).","commonSituations":"Adding many routes rapidly on macOS where the kernel route socket returns ENOBUFS; running unprivileged; interface state changed between socket creation and write (device gone => ENXIO).","solutions":["Inspect the wrapped errno: ENOBUFS => retry after a short delay or reduce route churn; EPERM => run as root.","Reduce the number of routes configured in tun.routes or add them more slowly if hitting kernel buffer limits.","Verify the utun interface is still up when routes are applied (it may have been torn down concurrently).","On macOS, consider sysctl tuning for route socket buffers if ENOBUFS recurs under heavy route churn."],"exampleFix":"// before: applying hundreds of routes at once\nroutes:\n  - route: 10.0.0.0/8\n    via: 10.1.1.1\n// after: aggregate to fewer, wider routes\nroutes:\n  - route: 10.0.0.0/16\n    via: 10.1.1.1","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := iface.Activate(); err != nil {\n    if strings.Contains(err.Error(), \"failed to write route.RouteMessage to socket\") && strings.Contains(err.Error(), \"no buffer space available\") {\n        // ENOBUFS: back off and re-activate once\n        time.Sleep(time.Second)\n        return iface.Activate()\n    }\n    return err\n}","preventionTips":["Aggregate tun.routes into fewer, wider prefixes to reduce route churn","Run as root to avoid EPERM writes","Add backoff between route additions when configuring many routes","On macOS with persistent ENOBUFS, tune route socket buffer sysctls"],"tags":["network","darwin","routing","socket-write"],"backgroundTag":"route-socket-write-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"}