netbirdio/netbird · critical

error creating tun device: %s

Error message

error creating tun device: %s

What it means

Userspace-mode Create() on linux/freebsd failed at tun.CreateTUN(name, mtu), which opens /dev/net/tun and performs the TUNSETIFF ioctl with the requested name and MTU. The interface name and MTU are logged at debug level alongside the wrapped cause. The tunnel cannot be created at all when this fires.

Source

Thrown at client/iface/device/device_usp_unix.go:51

func NewTunDevice(name string, address wgaddr.Address, port int, key string, mtu uint16, iceBind *bind.ICEBind) *TunDevice {
	log.Infof("using userspace bind mode")

	return &TunDevice{
		name:    name,
		address: address,
		port:    port,
		key:     key,
		mtu:     mtu,
		iceBind: iceBind,
	}
}

func (t *TunDevice) Create() (WGConfigurer, error) {
	log.Info("create tun interface")
	tunIface, err := tun.CreateTUN(t.name, int(t.mtu))
	if err != nil {
		log.Debugf("failed to create tun interface (%s, %d): %s", t.name, int(t.mtu), err)
		return nil, fmt.Errorf("error creating tun device: %s", err)
	}
	t.filteredDevice = newDeviceFilter(tunIface)

	// We need to create a wireguard-go device and listen to configuration requests
	t.device = device.NewDevice(
		t.filteredDevice,
		t.iceBind,
		device.NewLogger(wgLogLevel(), "[netbird] "),
	)

	err = t.assignAddr()
	if err != nil {
		t.device.Close()
		return nil, fmt.Errorf("error assigning ip: %s", err)
	}

	t.configurer = configurer.NewUSPConfigurer(t.device, t.name, t.iceBind.ActivityRecorder())
	err = t.configurer.ConfigureInterface(t.key, t.port)

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Run the agent as root or grant CAP_NET_ADMIN
  2. Load the tun module (modprobe tun) and verify /dev/net/tun exists
  3. In containers, start with --device /dev/net/tun --cap-add=NET_ADMIN
  4. Keep the interface name within 15 bytes (IFNAMSIZ-1)
Defensive patterns

Strategy: validation

Validate before calling

if _, err := os.Stat("/dev/net/tun"); err != nil {
    return fmt.Errorf("tun device missing: load the tun module or run the container with --device /dev/net/tun")
}
if os.Geteuid() != 0 {
    log.Warn("tun creation requires root or CAP_NET_ADMIN")
}

Try / catch

if _, err := dev.Create(); err != nil {
    if strings.Contains(err.Error(), "error creating tun device") {
        // environmental: check /dev/net/tun and privileges, do not retry unchanged
    }
    return err
}

Prevention

When it happens

Trigger: /dev/net/tun missing (tun module not loaded or not exposed to the container), EPERM from TUNSETIFF without CAP_NET_ADMIN, EINVAL for a name longer than 15 bytes or already in use with different flags.

Common situations: Docker/Podman runs missing --cap-add=NET_ADMIN --device /dev/net/tun; LXC/Proxmox containers without a tun device; hosts where the tun module is not loaded; overlong custom interface names.

Related errors


AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16). Data as JSON: /api/errors/7fd22be719fc492d. Report an issue: GitHub.