{"record":{"id":"955c3718ae458878","repo":"netbirdio/netbird","slug":"get-device-s-w","errorCode":null,"errorMessage":"get device %s: %w","messagePattern":"get device (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/iface/configurer/kernel_unix.go","lineNumber":231,"sourceCode":"\t}\n\treturn nil\n}\n\nfunc (c *KernelConfigurer) getPeer(ifaceName, peerPubKey string) (wgtypes.Peer, error) {\n\twg, err := wgctrl.New()\n\tif err != nil {\n\t\treturn wgtypes.Peer{}, fmt.Errorf(\"wgctl: %w\", err)\n\t}\n\tdefer func() {\n\t\terr = wg.Close()\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"Got error while closing wgctl: %v\", err)\n\t\t}\n\t}()\n\n\twgDevice, err := wg.Device(ifaceName)\n\tif err != nil {\n\t\treturn wgtypes.Peer{}, fmt.Errorf(\"get device %s: %w\", ifaceName, err)\n\t}\n\tfor _, peer := range wgDevice.Peers {\n\t\tif peer.PublicKey.String() == peerPubKey {\n\t\t\treturn peer, nil\n\t\t}\n\t}\n\treturn wgtypes.Peer{}, ErrPeerNotFound\n}\n\nfunc (c *KernelConfigurer) configure(config wgtypes.Config) error {\n\twg, err := wgctrl.New()\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer func() {\n\t\tif err := wg.Close(); err != nil {\n\t\t\tlog.Errorf(\"Failed to close wgctrl client: %v\", err)\n\t\t}","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/iface/configurer/kernel_unix.go#L213-L249","documentation":"Inside getPeer, wg.Device(ifaceName) failed. wgctrl returns an error wrapping os.ErrNotExist (ENODEV) when the named interface does not exist or is not a WireGuard device, and other netlink errors for transport problems. It surfaces wrapped as 'get peer: get device <name>: ...' from RemoveAllowedIP and RemoveEndpointAddress.","triggerScenarios":"Interface name typo or renamed device; interface deleted before the peer lookup; device exists but was created by a non-WireGuard driver; netlink transport error mid-query.","commonSituations":"NetBird interface (default wt0) already torn down when a route removal runs; custom interface name configured inconsistently between creation and configurer; agents in environments where another tool removed the link.","solutions":["Confirm the interface exists and is WireGuard: sudo wg show <deviceName>","Recreate the interface before reconfiguring peers if it was torn down","Match on errors.Is(err, os.ErrNotExist) and treat the peer operation as a no-op when the device is gone","Check for name mismatches when a custom interface name is configured"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// confirm the interface exists and is a WireGuard device before peer ops\nfunc wgDeviceExists(name string) bool {\n\tif _, err := net.InterfaceByName(name); err != nil {\n\t\treturn false\n\t}\n\twg, err := wgctrl.New()\n\tif err != nil {\n\t\treturn false\n\t}\n\tdefer wg.Close()\n\t_, err = wg.Device(name)\n\treturn err == nil\n}","typeGuard":null,"tryCatchPattern":"if err := kernelCfg.RemoveAllowedIP(peerKey, prefix); err != nil {\n\tif errors.Is(err, os.ErrNotExist) {\n\t\treturn nil // device gone: nothing left to configure\n\t}\n\treturn err\n}","preventionTips":["Verify the interface with 'wg show <name>' before scripting peer changes","Recreate the interface before reconfiguring peers after teardown","Use one constant for the interface name across creation and configuration","Drop configurer instances when the interface is deleted; never reuse them"],"tags":["wireguard","wgctrl","interface-management","netlink","go"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}