{"record":{"id":"38945c26d9558fe5","repo":"slackhq/nebula","slug":"a-device-name-in-the-format-of-dev-tunn-must-be-s","errorCode":null,"errorMessage":"a device name in the format of /dev/tunN must be specified","messagePattern":"a device name in the format of /dev/tunN must be specified","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"overlay/tun_netbsd.go","lineNumber":82,"sourceCode":"\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 NetBSD\")\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\n\terr = unix.SetNonblock(fd, true)\n\tif err != nil {\n\t\tl.Warn(\"Failed to set the tun device as nonblocking\", \"error\", err)\n\t}\n\n\tt := &tun{\n\t\tf:           os.NewFile(uintptr(fd), \"\"),\n\t\tfd:          fd,","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/overlay/tun_netbsd.go#L64-L100","documentation":"newTun on NetBSD requires the tun.dev config value to be a device name matching tunN (opened as /dev/tunN). This error is returned when tun.dev is empty, or when the value doesn't match the ^tun[0-9]+$ pattern. NetBSD has no automatic device naming, so an explicit valid name is mandatory.","triggerScenarios":"Starting the overlay on NetBSD with tun.dev unset, or set to something like 'tun', 'tunX', '/dev/tun0', 'eth0', or 'tun10x' — anything not matching tun followed by digits.","commonSituations":"Copying a Linux config (where tun.dev is optional) to NetBSD; including the /dev/ prefix in tun.dev even though the message mentions /dev/tunN; typo in the device name.","solutions":["Set tun.dev in config to a bare device name like 'tun0' (no /dev/ prefix).","Ensure the name matches tun[0-9]+ exactly — lowercase 'tun' followed only by digits.","Verify the device node exists: ls /dev/tun* and create it if your NetBSD setup requires (ifconfig tun0 create).","If migrating from Linux, remember tun.dev is required on NetBSD."],"exampleFix":"// before (config)\ntun:\n  dev: /dev/tun0   # wrong: includes /dev/ prefix\n// after\ntun:\n  dev: tun0","handlingStrategy":"validation","validationCode":"var deviceNameRE = regexp.MustCompile(`^tun[0-9]+$`)\nfunc validNetbsdTunDev(cfg string) bool {\n    return deviceNameRE.MatchString(cfg) // 'tun0' ok; '/dev/tun0' and '' are not\n}","typeGuard":null,"tryCatchPattern":"if err := startOverlay(c); err != nil {\n    if strings.Contains(err.Error(), \"device name in the format of /dev/tunN must be specified\") {\n        log.Error(\"set tun.dev to a bare name like 'tun0' (no /dev/ prefix)\")\n    }\n}","preventionTips":["Always set tun.dev on NetBSD — it is mandatory there","Use a bare name (tun0), never the /dev/ prefix, despite the message wording","Validate the value against ^tun[0-9]+$ before startup","Create the device node if missing: ifconfig tun0 create"],"tags":["netbsd","tun","config","validation"],"backgroundTag":"missing-or-invalid-config-value","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"}