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
- Run the agent as root or grant CAP_NET_ADMIN
- Load the tun module (modprobe tun) and verify /dev/net/tun exists
- In containers, start with --device /dev/net/tun --cap-add=NET_ADMIN
- 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
- Pre-flight /dev/net/tun and effective capabilities before bring-up
- In containers always pass --cap-add=NET_ADMIN --device /dev/net/tun
- Keep interface names within the 15-byte kernel limit
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
- error assigning ip: %s
- create ipset: %w
- failed to check rule: %w
- create ipset %s: %w
- add IP to ipset %s: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/7fd22be719fc492d.
Report an issue: GitHub.