slackhq/nebula · error

failed to run tun device: %s

Error message

failed to run tun device: %s

What it means

Raised in tun.Activate as the final step: the SIOCSIFFLAGS ioctl that sets IFF_UP|IFF_RUNNING on the tun interface fails. All prior setup (name, link, addresses, routes) succeeded, but the kernel refused to mark the device running.

Source

Thrown at overlay/tun_linux.go:508

		return fmt.Errorf("failed to bring the tun device up: %s", err)
	}

	//set route MTU
	for i := range t.vpnNetworks {
		if err = t.setDefaultRoute(t.vpnNetworks[i]); err != nil {
			return fmt.Errorf("failed to set default route MTU: %w", err)
		}
	}

	// Set the routes
	if err = t.addRoutes(false); err != nil {
		return err
	}

	// Run the interface
	ifrf.Flags = ifrf.Flags | unix.IFF_UP | unix.IFF_RUNNING
	if err = ioctl(t.ioctlFd, unix.SIOCSIFFLAGS, uintptr(unsafe.Pointer(&ifrf))); err != nil {
		return fmt.Errorf("failed to run tun device: %s", err)
	}

	return nil
}

func (t *tun) setMTU() {
	// Set the MTU on the device
	ifm := ifreqMTU{Name: t.deviceBytes(), MTU: int32(t.MaxMTU)}
	if err := ioctl(t.ioctlFd, unix.SIOCSIFMTU, uintptr(unsafe.Pointer(&ifm))); err != nil {
		// This is currently a non fatal condition because the route table must have the MTU set appropriately as well
		t.l.Error("Failed to set tun mtu", "error", err)
	}
}

func (t *tun) setDefaultRoute(cidr netip.Prefix) error {
	dr := &net.IPNet{
		IP:   cidr.Masked().Addr().AsSlice(),
		Mask: net.CIDRMask(cidr.Bits(), cidr.Addr().BitLen()),

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Run with root/CAP_NET_ADMIN so IFF_RUNNING can be set.
  2. Check %s errno: EPERM = privileges, ENODEV = device removed mid-activation.
  3. Ensure no external daemon deletes or reconfigures the tun during startup.
  4. Retry activation if transient.
Defensive patterns

Strategy: validation

Validate before calling

// privileges + device presence checked just before the final flags set
if os.Geteuid() != 0 && !hasCapNetAdmin() {
    return errors.New("setting IFF_UP|IFF_RUNNING requires CAP_NET_ADMIN")
}
if _, err := netlink.LinkByName(devName); err != nil {
    return fmt.Errorf("device %s vanished during activate", devName)
}

Try / catch

if err := t.Activate(netstack); err != nil {
    if strings.Contains(err.Error(), "failed to run tun device") {
        log.Error("could not set IFF_RUNNING; check privileges/device", "cause", err)
    }
}

Prevention

When it happens

Trigger: Activate() calls ioctl(t.ioctlFd, SIOCSIFFLAGS, ...) with Flags|IFF_UP|IFF_RUNNING and the kernel returns an error — permissions or the device disappeared late in setup.

Common situations: Missing CAP_NET_ADMIN; concurrent teardown by network management daemons; exotic kernels/seccomp profiles blocking SIOCSIFFLAGS.

Related errors


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