{"record":{"id":"5315d3c68541716c","repo":"netbirdio/netbird","slug":"error-removing-peer-s-from-interface-s-w","errorCode":null,"errorMessage":"error removing peer %s from interface %s: %w","messagePattern":"error removing peer (.+?) from interface (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/iface/configurer/kernel_unix.go","lineNumber":107,"sourceCode":"func (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\n\tif err := c.configure(wgtypes.Config{Peers: []wgtypes.PeerConfig{reAddPeerCfg}}); err != nil {\n\t\treturn fmt.Errorf(\n\t\t\t`error re-adding peer %s to interface %s with allowed IPs %v: %w`,\n\t\t\tpeerKey, c.deviceName, existingPeer.AllowedIPs, err,\n\t\t)\n\t}\n\n\treturn nil\n}","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/iface/configurer/kernel_unix.go#L89-L125","documentation":"The first half of RemoveEndpointAddress (remove the peer entirely so it can be re-added without an endpoint) failed at the wgctrl configure call. Because the strategy is delete-then-re-add, any error here is safe: the peer is still on the device with its old endpoint, so connectivity state is unchanged and the operation can simply be retried. The underlying causes are the usual kernel-configure ones: device vanished, permissions, or netlink transport failure.","triggerScenarios":"The WireGuard interface was removed between getPeer and the remove configure; losing CAP_NET_ADMIN mid-operation; netlink buffer exhaustion under heavy concurrent peer churn.","commonSituations":"Interface lifecycle races during engine restart; parallel peer updates from a fast-changing network map; agents on hosts where uapi sockets are intermittently unavailable (containerized or seccomp-restricted environments).","solutions":["Retry the whole RemoveEndpointAddress operation: no state was mutated, so the retry is safe","Confirm the device still exists before retrying; recreate the interface if it was torn down intentionally","Serialize peer mutations with a per-device lock to avoid netlink contention","If it persists, capture wg show output to compare the device state against the configurer's view"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if _, err := net.InterfaceByName(c.deviceName); err != nil {\n    return fmt.Errorf(\"device gone; skip removal: %w\", err)\n}","typeGuard":"func devicePresent(name string) bool {\n    _, err := net.InterfaceByName(name)\n    return err == nil\n}","tryCatchPattern":"err := configurer.RemoveEndpointAddress(peerKey)\nfor attempt := 0; attempt < 2 && err != nil; attempt++ {\n    if errors.Is(err, syscall.ENOENT) || errors.Is(err, syscall.EACCES) {\n        break // permanent: surface it\n    }\n    time.Sleep(50 * time.Millisecond)\n    err = configurer.RemoveEndpointAddress(peerKey) // remove step mutated nothing; safe to retry\n}","preventionTips":["Remember the remove half of the operation is state-preserving: retry is always safe","Serialize peer mutations per device to avoid netlink contention errors","Surface wrapped syscall causes in logs to separate races from permission problems"],"tags":["go","netbird","wireguard","kernel","peers","retry"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}