{"record":{"id":"2636b4b91ca81617","repo":"netbirdio/netbird","slug":"link-add-w","errorCode":null,"errorMessage":"link add: %w","messagePattern":"link add: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"client/iface/device/wg_link_linux.go","lineNumber":72,"sourceCode":"\t\tdefault:\n\t\t\treturn fmt.Errorf(\"link by name: %w\", err)\n\t\t}\n\t}\n\n\t// remove if interface exists\n\tif link != nil {\n\t\terr = netlink.LinkDel(l)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tlog.Debugf(\"adding device: %s\", name)\n\terr = netlink.LinkAdd(l)\n\tif os.IsExist(err) {\n\t\tlog.Infof(\"interface %s already exists. Will reuse.\", name)\n\t} else if err != nil {\n\t\treturn fmt.Errorf(\"link add: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc (l *wgLink) setMTU(mtu int) error {\n\tif err := netlink.LinkSetMTU(l, mtu); err != nil {\n\t\tlog.Errorf(\"error setting MTU on interface: %s\", l.attrs.Name)\n\n\t\treturn fmt.Errorf(\"link set mtu: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc (l *wgLink) up() error {\n\tif err := netlink.LinkSetUp(l); err != nil {\n\t\tlog.Errorf(\"error bringing up interface: %s\", l.attrs.Name)","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/iface/device/wg_link_linux.go#L54-L90","documentation":"netlink.LinkAdd(l) failed with an error other than EEXIST (EEXIST is tolerated with 'interface already exists, will reuse'). The link reports Type() \"wireguard\", so RTM_NEWLINK requires the wireguard kernel module; an unsupported kind, missing privileges, or an invalid name are the classic causes. This is the kernel-mode interface creation step and is fatal to bring-up.","triggerScenarios":"wireguard module unavailable (unsupported kind error), EPERM without CAP_NET_ADMIN, EINVAL for a name over 15 bytes or invalid attributes, ENOMEM/ENFILE at the interface limit.","commonSituations":"Old or custom kernels without wireguard, stripped module sets in minimal images, overlong interface names, kernel/userspace mode selection picking kernel mode on an unsupported host.","solutions":["Load the module (modprobe wireguard) or install matching kernel modules and run depmod","Run with root/CAP_NET_ADMIN","Shorten the interface name to 15 bytes or fewer","If the kernel cannot provide wireguard, force userspace mode with NB_WG_KERNEL_DISABLED=true or rely on the automatic userspace fallback"],"exampleFix":"// before\nif err := l.recreate(); err != nil {\n    return err\n}\n\n// after\nif !device.WireGuardModuleIsLoaded() {\n    return fmt.Errorf(\"kernel wireguard unavailable; run in userspace mode\")\n}\nif err := l.recreate(); err != nil {\n    return err\n}","handlingStrategy":"validation","validationCode":"if !device.WireGuardModuleIsLoaded() {\n    // no kernel wireguard: use userspace mode instead of attempting LinkAdd\n    return useUserspaceMode()\n}\nif len(ifaceName) > 15 {\n    return fmt.Errorf(\"interface name %q exceeds 15 bytes\", ifaceName)\n}","typeGuard":null,"tryCatchPattern":"if err := netlink.LinkAdd(l); err != nil && !os.IsExist(err) {\n    if errors.Is(err, syscall.EPERM) {\n        // missing CAP_NET_ADMIN\n    } else if errors.Is(err, syscall.EPROTONOSUPPORT) || errors.Is(err, syscall.EOPNOTSUPP) {\n        // wireguard kind unsupported: module missing\n    }\n    return fmt.Errorf(\"link add: %w\", err)\n}","preventionTips":["Probe WireGuardModuleIsLoaded() before choosing kernel mode","Keep interface names within 15 bytes","Set NB_WG_KERNEL_DISABLED=true on hosts that cannot load the wireguard module"],"tags":["linux","netlink","wireguard","kernel-module","permissions"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}