{"record":{"id":"d5a29646db147ab4","repo":"slackhq/nebula","slug":"newtunfromfd-not-supported-in-openbsd","errorCode":null,"errorMessage":"newTunFromFd not supported in openbsd","messagePattern":"newTunFromFd not supported in openbsd","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"overlay/tun_openbsd.go","lineNumber":65,"sourceCode":"\tName [unix.IFNAMSIZ]byte\n\tdata int\n}\n\ntype tun struct {\n\tDevice      string\n\tvpnNetworks []netip.Prefix\n\tMTU         int\n\tRoutes      atomic.Pointer[[]Route]\n\trouteTree   atomic.Pointer[bart.Table[routing.Gateways]]\n\tl           *slog.Logger\n\tf           *os.File\n\tfd          int\n}\n\nvar deviceNameRE = regexp.MustCompile(`^tun[0-9]+$`)\n\nfunc newTunFromFd(_ *config.C, _ *slog.Logger, _ int, _ []netip.Prefix) (*tun, error) {\n\treturn nil, fmt.Errorf(\"newTunFromFd not supported in openbsd\")\n}\n\nfunc newTun(c *config.C, l *slog.Logger, vpnNetworks []netip.Prefix, _ bool) (*tun, error) {\n\t// Try to open tun device\n\tvar err error\n\tdeviceName := c.GetString(\"tun.dev\", \"\")\n\tif deviceName == \"\" {\n\t\treturn nil, fmt.Errorf(\"a device name in the format of /dev/tunN must be specified\")\n\t}\n\tif !deviceNameRE.MatchString(deviceName) {\n\t\treturn nil, fmt.Errorf(\"a device name in the format of /dev/tunN must be specified\")\n\t}\n\n\tfd, err := unix.Open(\"/dev/\"+deviceName, os.O_RDWR, 0)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/overlay/tun_openbsd.go#L47-L83","documentation":"On OpenBSD, creating a tun device from an existing file descriptor is not implemented; newTunFromFd is a stub that always returns this error. The library only supports opening tun devices by device name (via newTun) on this platform. Any caller or config path that resolves to newTunFromFd on OpenBSD will fail immediately.","triggerScenarios":"Calling newTunFromFd directly, or using a config/injection path (e.g. passing an inherited tun fd) that routes to newTunFromFd on an OpenBSD build.","commonSituations":"Portable deployments that pass an already-open tun fd from a parent process (common with privilege-separation designs) running on OpenBSD; copied Linux configuration files that set tun file-descriptor options.","solutions":["On OpenBSD, use the device-name path: set tun.dev to a valid device (e.g. tun0) so newTun is used instead.","Remove any fd-passing configuration that triggers newTunFromFd on OpenBSD.","If fd inheritance is required, pre-open /dev/tunN in the parent and pass the device name to the child instead of the raw fd.","Check for a newer library version that may implement fd-based tun creation on OpenBSD."],"exampleFix":"// before (config triggering fd path)\n tun:\n   fd: 7\n// after (OpenBSD: use device name)\n tun:\n   dev: tun0","handlingStrategy":"fallback","validationCode":"// Choose the right constructor per platform before calling\nfunc openTun(c *config.C, l *slog.Logger, fd int, networks []netip.Prefix) (*tun, error) {\n    if fd >= 0 && runtime.GOOS == \"openbsd\" {\n        return nil, fmt.Errorf(\"fd-based tun is unsupported on openbsd; set tun.dev instead\")\n    }\n    if fd >= 0 {\n        return newTunFromFd(c, l, fd, networks)\n    }\n    return newTun(c, l, networks, false)\n}","typeGuard":null,"tryCatchPattern":"t, err := openTun(cfg, log, fd, networks)\nif err != nil && strings.Contains(err.Error(), \"not supported in openbsd\") {\n    // Fallback: open by device name\n    devName := cfg.GetString(\"tun.dev\", \"tun0\")\n    return fmt.Errorf(\"newTunFromFd unavailable; configure tun.dev (e.g. %s) instead: %w\", devName, err)\n}","preventionTips":["On OpenBSD always configure tun.dev with a valid device name (tun0, tun1, ...).","Do not use fd-passing / privilege-separation tun setups on OpenBSD builds.","Gate fd-based tun code paths behind runtime.GOOS checks.","Match device names against the tun[0-9]+ pattern the library requires."],"tags":["openbsd","tun","unsupported","platform"],"backgroundTag":"unsupported-platform-feature","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"}