{"record":{"id":"6219f72354036859","repo":"slackhq/nebula","slug":"failed-to-run-tun-device-s","errorCode":null,"errorMessage":"failed to run tun device: %s","messagePattern":"failed to run tun device: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"overlay/tun_darwin.go","lineNumber":217,"sourceCode":"\n\tfor _, network := range t.vpnNetworks {\n\t\tif network.Addr().Is4() {\n\t\t\terr = t.activate4(network)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t} else {\n\t\t\terr = t.activate6(network)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\n\t// Run the interface\n\tifrf.Flags = ifrf.Flags | unix.IFF_UP | unix.IFF_RUNNING\n\tif err = ioctl(fd, unix.SIOCSIFFLAGS, uintptr(unsafe.Pointer(&ifrf))); err != nil {\n\t\treturn fmt.Errorf(\"failed to run tun device: %s\", err)\n\t}\n\n\t// Unsafe path routes\n\treturn t.addRoutes(false)\n}\n\nfunc (t *tun) activate4(network netip.Prefix) error {\n\ts, err := unix.Socket(\n\t\tunix.AF_INET,\n\t\tunix.SOCK_DGRAM,\n\t\tunix.IPPROTO_IP,\n\t)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer unix.Close(s)\n\n\tifr := ifreqAlias4{","sourceCodeStart":199,"sourceCodeEnd":235,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/overlay/tun_darwin.go#L199-L235","documentation":"During Activate(), after the utun interface has been created and given an address, nebula sets the interface flags via the SIOCSIFFLAGS ioctl to mark it IFF_UP and IFF_RUNNING. This error wraps the raw errno when that ioctl fails, meaning the kernel refused to bring the utun device up. It indicates the interface name in the ioctl request no longer matches a live kernel network interface.","triggerScenarios":"Activate() is called at tun setup; the SIOCSIFFLAGS ioctl on the AF_INET UDP control socket fails (e.g. the utun unit number requested in tun.dev was taken so the actual device differs, or the interface disappeared between SIOCGIFFLAGS and SIOCSIFFLAGS).","commonSituations":"Running on a macOS/Darwin host where another nebula instance or VPN client already claimed the requested utunN unit; sandboxed/containerized environments where utun devices are not permitted; stale device names after the previous process exited without closing the tun.","solutions":["Check the error's underlying errno via the %s suffix (e.g. ENXIO/ENODEV means the device is gone) and confirm the utun interface still exists with `ifconfig`.","Remove any explicit tun.dev setting (or set it to `utun`) so nebula picks the next available utun unit instead of a fixed number.","Stop any other VPN/nebula processes that may have claimed the requested utun index.","Ensure nebula is not running inside a container/sandbox that blocks utun kernel control requests; run it on the host or grant the needed entitlements."],"exampleFix":"// before (fixed unit, may collide)\ntun:\n  dev: utun7\n// after (let the kernel pick a free unit)\ntun:\n  dev: utun","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := iface.Activate()\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to run tun device\") {\n        // retry with auto-selected utun unit (tun.dev: utun) after checking `ifconfig`\n    }\n    return err\n}","preventionTips":["Leave tun.dev unset or set to `utun` so the kernel assigns a free unit","Ensure only one nebula/VPN instance runs at a time","Verify with `ifconfig` that the utun interface exists before/after start","Run on the host, not inside a sandbox that blocks utun control ioctls"],"tags":["network","darwin","ioctl","tun-device"],"backgroundTag":"tun-ioctl-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"}