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

  1. Verify the interface exists: ip link show <devName>; recreate the tun if it's gone.
  2. Check the %s errno — ENODEV means the named device doesn't exist, EBADF/ENOTTY means the fd is wrong.
  3. Stop network management daemons from removing/reconfiguring the interface during startup (unmanaged-device config).
  4. Ensure the process has CAP_NET_ADMIN to issue interface ioctls.
  5. 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

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


AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03). Data as JSON: /api/errors/12af9c0a304c1dce. Report an issue: GitHub.