{"record":{"id":"85bb32d5522b39f1","repo":"netbirdio/netbird","slug":"get-peer-w","errorCode":null,"errorMessage":"get peer: %w","messagePattern":"get peer: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/iface/configurer/kernel_unix.go","lineNumber":98,"sourceCode":"\t\tPeers: []wgtypes.PeerConfig{peer},\n\t}\n\terr = c.configure(config)\n\tif err != nil {\n\t\treturn fmt.Errorf(`received error \"%w\" while updating peer on interface %s with settings: allowed ips %s, endpoint %s`, err, c.deviceName, allowedIps, endpoint.String())\n\t}\n\treturn nil\n}\n\nfunc (c *KernelConfigurer) RemoveEndpointAddress(peerKey string) error {\n\tpeerKeyParsed, err := wgtypes.ParseKey(peerKey)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Get the existing peer to preserve its allowed IPs\n\texistingPeer, err := c.getPeer(c.deviceName, peerKey)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"get peer: %w\", err)\n\t}\n\n\tremovePeerCfg := wgtypes.PeerConfig{\n\t\tPublicKey: peerKeyParsed,\n\t\tRemove:    true,\n\t}\n\n\tif err := c.configure(wgtypes.Config{Peers: []wgtypes.PeerConfig{removePeerCfg}}); err != nil {\n\t\treturn fmt.Errorf(`error removing peer %s from interface %s: %w`, peerKey, c.deviceName, err)\n\t}\n\n\t//Re-add the peer without the endpoint but same AllowedIPs\n\treAddPeerCfg := wgtypes.PeerConfig{\n\t\tPublicKey:         peerKeyParsed,\n\t\tAllowedIPs:        existingPeer.AllowedIPs,\n\t\tReplaceAllowedIPs: true,\n\t}\n","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/iface/configurer/kernel_unix.go#L80-L116","documentation":"RemoveEndpointAddress first reads the current peer state via getPeer so it can preserve the allowed IPs when re-adding the peer without its endpoint. That read failed, which on the kernel path means wgctrl could not return the peer: the device does not exist (ENOENT), the peer key is not present on the device, or the netlink/uapi transport errored (permissions, interrupted syscall).","triggerScenarios":"Removing an endpoint for a peer that was already removed from the device (e.g. after a ReplacePeers configure or full peer resync); the interface being torn down concurrently; an invalid peer public key string that fails wgtypes.ParseKey earlier or a device enumeration failure under load.","commonSituations":"Engine reconfiguration flows (network map change, peer removal from group) racing a full device re-setup; duplicated removal requests where the first one already succeeded; unclean prior shutdown leaving the configurer pointing at a dead device.","solutions":["Treat unknown-peer/device causes as idempotent success when the goal state is 'peer without endpoint', instead of propagating the error","Retry once after confirming the interface still exists (ip link show / wg show) before failing the operation","Serialize remove operations with device resync so ReplacePeers cannot wipe the peer mid-operation","Check the wrapped wgctrl error text to distinguish 'no such device' from 'no such peer'"],"exampleFix":"// before\nexistingPeer, err := c.getPeer(c.deviceName, peerKey)\nif err != nil { return fmt.Errorf(\"get peer: %w\", err) }\n\n// after\nexistingPeer, err := c.getPeer(c.deviceName, peerKey)\nif err != nil {\n    if isPeerOrDeviceGone(err) {\n        return nil // desired state already reached\n    }\n    return fmt.Errorf(\"get peer: %w\", err)\n}","handlingStrategy":"validation","validationCode":"// confirm the peer exists before endpoint removal\nif _, err := getPeer(deviceName, peerKey); err != nil {\n    if isNotFound(err) {\n        return nil // nothing to remove; desired state\n    }\n    return err\n}","typeGuard":"func peerExists(deviceName, peerKey string) bool {\n    client, err := wgctrl.New()\n    if err != nil {\n        return false\n    }\n    defer client.Close()\n    d, err := client.Device(deviceName)\n    if err != nil {\n        return false\n    }\n    for _, p := range d.Peers {\n        if p.PublicKey.String() == peerKey {\n            return true\n        }\n    }\n    return false\n}","tryCatchPattern":"if err := configurer.RemoveEndpointAddress(peerKey); err != nil {\n    if strings.Contains(err.Error(), \"get peer\") && isNotFound(err) {\n        return nil // idempotent success\n    }\n    return err\n}","preventionTips":["Make endpoint removal idempotent: not-found is the goal state","Deduplicate removal events so the second one does not hit a missing peer","Never run endpoint removal concurrently with a full peer resync that uses ReplacePeers"],"tags":["go","netbird","wireguard","kernel","peers","idempotency"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}