slackhq/nebula · error
failed to set tun device name: %s
Error message
failed to set tun device name: %s
What it means
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.
Source
Thrown at overlay/tun_linux.go:458
if t.useSystemRoutes {
t.watchRoutes()
}
s, err := unix.Socket(
unix.AF_INET, //because everything we use t.ioctlFd for is address family independent, this is fine
unix.SOCK_DGRAM,
unix.IPPROTO_IP,
)
if err != nil {
return err
}
t.ioctlFd = uintptr(s)
// Set the device name
ifrf := ifReq{Name: devName}
if err = ioctl(t.ioctlFd, unix.SIOCGIFFLAGS, uintptr(unsafe.Pointer(&ifrf))); err != nil {
return fmt.Errorf("failed to set tun device name: %s", err)
}
link, err := netlink.LinkByName(t.Device)
if err != nil {
return fmt.Errorf("failed to get tun device link: %s", err)
}
t.deviceIndex = link.Attrs().Index
// Setup our default MTU
t.setMTU()
// Set the transmit queue length
ifrq := ifreqQLEN{Name: devName, Value: int32(t.TXQueueLen)}
if err = ioctl(t.ioctlFd, unix.SIOCSIFTXQLEN, uintptr(unsafe.Pointer(&ifrq))); err != nil {
// If we can't set the queue length nebula will still work but it may lead to packet loss
t.l.Error("Failed to set tun tx queue length", "error", err)
}View on GitHub (pinned to dd8f660c0a)
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).
Defensive patterns
Strategy: validation
Validate before calling
// verify device exists and is controllable before Activate
out, err := exec.Command("ip", "link", "show", devName).CombinedOutput()
if err != nil { return fmt.Errorf("device %s absent: %v: %s", devName, err, out) } Try / catch
if err := t.Activate(netstack); err != nil {
if strings.Contains(err.Error(), "failed to set tun device name") {
log.Error("tun device unavailable/removed during activate", "cause", err)
}
} Prevention
- Mark the tun device unmanaged in NetworkManager/systemd-networkd
- Verify tun.dev matches an existing interface name
- Ensure the process holds CAP_NET_ADMIN
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- failed to enable offload on multiqueue tun fd: %w
- failed to run tun device: %s
- failed to get tun address list: %s
- failed to get tun device link: %s
- failed to bring the tun device up: %s
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/12af9c0a304c1dce.
Report an issue: GitHub.