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
- Run with root/CAP_NET_ADMIN so IFF_RUNNING can be set.
- Check %s errno: EPERM = privileges, ENODEV = device removed mid-activation.
- Ensure no external daemon deletes or reconfigures the tun during startup.
- 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
- Run with root/CAP_NET_ADMIN
- Confirm no concurrent teardown of the tun during activation
- Check seccomp/apparmor profiles don't block SIOCSIFFLAGS
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
- failed to enable offload on multiqueue tun fd: %w
- failed to set tun device name: %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/3a7c2a60beee5d51.
Report an issue: GitHub.