{"record":{"id":"81a7c01b7e28c338","repo":"slackhq/nebula","slug":"failed-to-create-route-routemessage-w-81a7c0","errorCode":null,"errorMessage":"failed to create route.RouteMessage: %w","messagePattern":"failed to create route\\.RouteMessage: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"overlay/tun_openbsd.go","lineNumber":462,"sourceCode":"\t\t\tunix.RTAX_DST:     &netroute.Inet4Addr{IP: prefix.Masked().Addr().As4()},\n\t\t\tunix.RTAX_NETMASK: &netroute.Inet4Addr{IP: prefixToMask(prefix).As4()},\n\t\t\tunix.RTAX_GATEWAY: &netroute.Inet4Addr{IP: gw.Addr().As4()},\n\t\t}\n\t} else {\n\t\tgw, err := selectGateway(prefix, gateways)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\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: &netroute.Inet6Addr{IP: gw.Addr().As16()},\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\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","sourceCodeStart":444,"sourceCodeEnd":480,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/overlay/tun_openbsd.go#L444-L480","documentation":"In overlay/tun_openbsd.go addRoute, the route.RouteMessage built for adding a route to the OpenBSD routing socket fails route.Marshal(). This means the message could not be serialized into the binary wire format the kernel routing socket expects. It is a programming/configuration error in the route parameters (address family, addresses, flags), not a transient network problem.","triggerScenarios":"addRoute (called by addIp or addRoutes) constructs a netroute.RouteMessage with an invalid combination of fields (e.g. unsupported address family, malformed netip.Addr conversion via As16, wrong RTAX index) so route.Marshal() returns an error.","commonSituations":"Running nebula on OpenBSD with a VPN network prefix or gateway whose family doesn't match the branch that builds the message; porting changes to the route-message construction; unusual tunnel::routes config entries that produce IPv4 routes through the IPv6 branch or vice versa.","solutions":["Check the tun.routes / tun.unsafe_routes config: ensure each route's prefix and gateway address family is consistent (IPv4 prefix with IPv4 gateway, IPv6 with IPv6).","Confirm the gateway netip.Prefix has a valid Addr (not the zero value) before As16() is called; fix the calling config.","Check the OpenBSD/Go version compatibility of golang.org/x/net/netroute (internal API changed across versions) and update dependencies to a known-good combo.","If you patched addRoute, verify all RTAX_* attributes you set are valid for RTM_ADD and that Inet4Addr/Inet6Addr types match the message's Addrs bitmap."],"exampleFix":"// before\n// IPv4 route reaching the IPv6 gateway branch\nunix.RTAX_GATEWAY: &netroute.Inet6Addr{IP: gw.Addr().As16()},\n// after\n// branch by family\nif gw.Addr().Is4() {\n\tattrs[unix.RTAX_GATEWAY] = &netroute.Inet4Addr{IP: gw.Addr().As4()}\n} else {\n\tattrs[unix.RTAX_GATEWAY] = &netroute.Inet6Addr{IP: gw.Addr().As16()}\n}","handlingStrategy":"validation","validationCode":"for _, r := range routes {\n\tif !r.Gateway.IsValid() || r.Gateway.Addr().Is4() != r.Route.Addr().Is4() {\n\t\treturn fmt.Errorf(\"route %s gateway %s family mismatch\", r.Route, r.Gateway)\n\t}\n}","typeGuard":null,"tryCatchPattern":"if err := overlay.AddRoutes(routes); err != nil {\n\tvar marshalErr error\n\tif errors.Unwrap(err) != nil && strings.Contains(err.Error(), \"Marshal\") {\n\t\tmarshalErr = err // invalid route message; fix config, not retryable\n\t}\n}","preventionTips":["Keep IPv4 prefixes paired with IPv4 gateways in tun.routes.","Validate route config at startup before applying routes.","Pin golang.org/x/net to a version tested with your Go toolchain."],"tags":["openbsd","routing","route-socket","serialization"],"backgroundTag":"route-marshal-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"}