{"record":{"id":"da9c7b015e26a2c3","repo":"slackhq/nebula","slug":"failed-to-create-route-routemessage-for-change-w-da9c7b","errorCode":null,"errorMessage":"failed to create route.RouteMessage for change: %w","messagePattern":"failed to create route\\.RouteMessage for change: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"overlay/tun_openbsd.go","lineNumber":472,"sourceCode":"\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\n}\n\nfunc delRoute(prefix netip.Prefix, gateways []netip.Prefix) 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{","sourceCodeStart":454,"sourceCodeEnd":490,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/overlay/tun_openbsd.go#L454-L490","documentation":"After an RTM_ADD write fails with EEXIST, addRoute retries with an RTM_CHANGE message and re-marshals the RouteMessage. If Marshal() fails on this second attempt, the error is wrapped as 'failed to create route.RouteMessage for change'. As with the add case, it indicates the in-memory route message cannot be serialized for the kernel.","triggerScenarios":"The first unix.Write returned unix.EEXIST (route already present), route.Type was set to unix.RTM_CHANGE, and the re-Marshal of the same route data returned an error — i.e. the same invalid field combination as error 460, encountered on the change path.","commonSituations":"Re-adding an existing route (EEXIST path) on OpenBSD with a malformed gateway/prefix from config; library version drift in x/net/route making the message invalid for both add and change.","solutions":["Validate the route prefix/gateway families in tun.routes config so the RouteMessage fields are always well-formed.","Update golang.org/x/net to a version compatible with your Go toolchain, since netroute internals can shift.","Inspect any local modifications to addRoute; RTM_CHANGE messages must not include attributes the kernel rejects (e.g. gateway type mismatch).","Log the failing route prefix and gateway at debug level to identify the offending config entry."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// same family/validity check as the add path\nfor _, r := range routes {\n\tif !r.Gateway.IsValid() {\n\t\treturn fmt.Errorf(\"invalid gateway for %s\", r.Route)\n\t}\n}","typeGuard":null,"tryCatchPattern":"if err := addRoute(prefix, gateways); err != nil {\n\tif strings.Contains(err.Error(), \"for change\") {\n\t\t// non-retryable serialization failure; log route details and abort\n\t}\n}","preventionTips":["Don't rely on the EEXIST->RTM_CHANGE fallback for malformed routes; fix the input instead.","Log prefix/gateway when route application fails to identify bad config entries.","Test route add/change/delete on your OpenBSD release after dependency upgrades."],"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"}