{"record":{"id":"f6438d7ce8530603","repo":"slackhq/nebula","slug":"failed-to-write-route-routemessage-to-socket-w-f6438d","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_freebsd.go","lineNumber":659,"sourceCode":"\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\tif errors.Is(err, unix.EEXIST) {\n\t\t\t// Try to do a change\n\t\t\troute.Type = unix.RTM_CHANGE\n\t\t\tdata, err = route.Marshal()\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to create route.RouteMessage for change: %w\", err)\n\t\t\t}\n\t\t\t_, err = unix.Write(sock, data[:])\n\t\t\treturn err\n\t\t}\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":641,"sourceCodeEnd":677,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/overlay/tun_freebsd.go#L641-L677","documentation":"addRoute (overlay/tun_freebsd.go:659) writes the marshaled route.RouteMessage (RTM_ADD) to the AF_ROUTE socket with unix.Write. This error wraps any failure of that write, meaning the kernel routing socket rejected the route-add message.","triggerScenarios":"unix.Write(sock, data) returns an error when submitting an RTM_ADD message: socket closed, permission denied (non-root), or the kernel rejecting the message (invalid/ambiguous route, ENOBUFS).","commonSituations":"Running nebula without CAP_NET_ADMIN/root privileges so the route socket write fails with EPERM; kernel rejecting a duplicate or malformed route; resource exhaustion (ENOBUFS) under heavy route churn on busy FreeBSD hosts.","solutions":["Run nebula as root or with the privileges needed to modify the routing table (the process needs write access to the route socket).","Inspect the wrapped errno in the message to identify the kernel rejection reason (EPERM, ENETUNREACH, ENOBUFS).","Verify the route/gateway is valid and reachable per the interface configuration.","Retry on transient errors like ENOBUFS; addRoutes is typically invoked at startup or reload."],"exampleFix":"// before (run as unprivileged user)\n$ nebula -config config.yml\n// after\n$ sudo nebula -config config.yml","handlingStrategy":"try-catch","validationCode":"// Go: check privileges before attempting route writes\nif os.Geteuid() != 0 {\n\treturn errors.New(\"adding routes requires root or CAP_NET_ADMIN\")\n}","typeGuard":null,"tryCatchPattern":"if _, err := unix.Write(sock, data[:]); err != nil {\n\tif errors.Is(err, unix.ENOBUFS) {\n\t\t// transient: retry with backoff\n\t} else {\n\t\treturn fmt.Errorf(\"failed to write route.RouteMessage to socket: %w\", err)\n\t}\n}","preventionTips":["Run nebula as root or with CAP_NET_ADMIN on FreeBSD.","Retry transient ENOBUFS failures with backoff under route churn.","Log the wrapped errno to distinguish permission vs resource issues."],"tags":["freebsd","routing","network","permissions"],"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"}