{"record":{"id":"12af9c0a304c1dce","repo":"slackhq/nebula","slug":"failed-to-set-tun-device-name-s","errorCode":null,"errorMessage":"failed to set tun device name: %s","messagePattern":"failed to set tun device name: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"overlay/tun_linux.go","lineNumber":458,"sourceCode":"\n\tif t.useSystemRoutes {\n\t\tt.watchRoutes()\n\t}\n\n\ts, err := unix.Socket(\n\t\tunix.AF_INET, //because everything we use t.ioctlFd for is address family independent, this is fine\n\t\tunix.SOCK_DGRAM,\n\t\tunix.IPPROTO_IP,\n\t)\n\tif err != nil {\n\t\treturn err\n\t}\n\tt.ioctlFd = uintptr(s)\n\n\t// Set the device name\n\tifrf := ifReq{Name: devName}\n\tif err = ioctl(t.ioctlFd, unix.SIOCGIFFLAGS, uintptr(unsafe.Pointer(&ifrf))); err != nil {\n\t\treturn fmt.Errorf(\"failed to set tun device name: %s\", err)\n\t}\n\n\tlink, err := netlink.LinkByName(t.Device)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get tun device link: %s\", err)\n\t}\n\n\tt.deviceIndex = link.Attrs().Index\n\n\t// Setup our default MTU\n\tt.setMTU()\n\n\t// Set the transmit queue length\n\tifrq := ifreqQLEN{Name: devName, Value: int32(t.TXQueueLen)}\n\tif err = ioctl(t.ioctlFd, unix.SIOCSIFTXQLEN, uintptr(unsafe.Pointer(&ifrq))); err != nil {\n\t\t// If we can't set the queue length nebula will still work but it may lead to packet loss\n\t\tt.l.Error(\"Failed to set tun tx queue length\", \"error\", err)\n\t}","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/overlay/tun_linux.go#L440-L476","documentation":"Raised in tun.Activate right after opening the tun control fd: the SIOCGIFFLAGS ioctl on the new device fails while trying to read/apply the device name flags (ifReq with devName). Despite the wording, it wraps the classic 'get interface flags' ioctl failure for the tun device.","triggerScenarios":"Activate() is called and ioctl(t.ioctlFd, SIOCGIFFLAGS, ...) returns an error — typically because the device name doesn't exist, the fd is invalid, or the interface was removed between creation and activation.","commonSituations":"tun.dev configured with a name that clashes or was already torn down; interface deleted by network managers (NetworkManager/systemd-networkd) mid-setup; running in a container without the tun device present.","solutions":["Verify the interface exists: ip link show <devName>; recreate the tun if it's gone.","Check the %s errno — ENODEV means the named device doesn't exist, EBADF/ENOTTY means the fd is wrong.","Stop network management daemons from removing/reconfiguring the interface during startup (unmanaged-device config).","Ensure the process has CAP_NET_ADMIN to issue interface ioctls.","Retry Activate() if the failure was transient (device hotplug race)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// verify device exists and is controllable before Activate\nout, err := exec.Command(\"ip\", \"link\", \"show\", devName).CombinedOutput()\nif err != nil { return fmt.Errorf(\"device %s absent: %v: %s\", devName, err, out) }","typeGuard":null,"tryCatchPattern":"if err := t.Activate(netstack); err != nil {\n    if strings.Contains(err.Error(), \"failed to set tun device name\") {\n        log.Error(\"tun device unavailable/removed during activate\", \"cause\", err)\n    }\n}","preventionTips":["Mark the tun device unmanaged in NetworkManager/systemd-networkd","Verify tun.dev matches an existing interface name","Ensure the process holds CAP_NET_ADMIN"],"tags":["network","tun","linux","ioctl"],"backgroundTag":"ioctl-siocgifflags-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"}