{"record":{"id":"5a0e670d81b25164","repo":"netbirdio/netbird","slug":"peer-s-not-found","errorCode":null,"errorMessage":"peer %s not found","messagePattern":"peer (.+?) not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/iface/configurer/usp.go","lineNumber":159,"sourceCode":"\t}\n\n\t// Parse current status to get allowed IPs for the peer\n\tstats, err := parseStatus(c.deviceName, ipcStr)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"parse IPC config: %w\", err)\n\t}\n\n\tvar allowedIPs []net.IPNet\n\tfound := false\n\tfor _, peer := range stats.Peers {\n\t\tif peer.PublicKey == peerKey {\n\t\t\tallowedIPs = peer.AllowedIPs\n\t\t\tfound = true\n\t\t\tbreak\n\t\t}\n\t}\n\tif !found {\n\t\treturn fmt.Errorf(\"peer %s not found\", peerKey)\n\t}\n\n\t// remove the peer from the WireGuard configuration\n\tpeer := wgtypes.PeerConfig{\n\t\tPublicKey: peerKeyParsed,\n\t\tRemove:    true,\n\t}\n\n\tconfig := wgtypes.Config{\n\t\tPeers: []wgtypes.PeerConfig{peer},\n\t}\n\tif ipcErr := c.device.IpcSet(toWgUserspaceString(config)); ipcErr != nil {\n\t\treturn fmt.Errorf(\"failed to remove peer: %s\", ipcErr)\n\t}\n\n\t// Build the peer config\n\tpeer = wgtypes.PeerConfig{\n\t\tPublicKey:         peerKeyParsed,","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/iface/configurer/usp.go#L141-L177","documentation":"WGUSPConfigurer.RemoveEndpointAddress scanned the parsed IPC dump for the peer's public key and found no match, so there is no endpoint to clear. The peer must already exist in the userspace device's live state for this operation to make sense. Typically the peer was already removed (or never added) by the time the call ran.","triggerScenarios":"RemoveEndpointAddress called after RemovePeer; network-map update removed the peer concurrently; peer key string in a different format than the one stored (base64 vs the parsed stats' base64 form); peer never added because connection setup failed earlier.","commonSituations":"Connection-close handler racing a management update that drops the peer; teardown code clearing endpoints for all peers after mass removal; embedded client shutdown ordering.","solutions":["Treat a missing peer as success: there is no endpoint left to remove","Call RemoveEndpointAddress before RemovePeer in teardown sequences","Re-check with FullStats if you need to distinguish 'already gone' from a key-format mismatch","Guard concurrent peer mutations with a lock so removal and endpoint clearing cannot interleave"],"exampleFix":"// before\nif !found {\n\treturn fmt.Errorf(\"peer %s not found\", peerKey)\n}\n\n// after: clearing the endpoint of an absent peer is a no-op\nif !found {\n\treturn nil\n}","handlingStrategy":"validation","validationCode":"// confirm the peer exists before clearing its endpoint\nstats, err := uspCfg.FullStats()\nif err != nil {\n\treturn err\n}\nfor _, p := range stats.Peers {\n\tif p.PublicKey == peerKey {\n\t\treturn uspCfg.RemoveEndpointAddress(peerKey)\n\t}\n}\nreturn nil // peer absent: nothing to clear","typeGuard":null,"tryCatchPattern":"if err := uspCfg.RemoveEndpointAddress(peerKey); err != nil {\n\tif strings.Contains(err.Error(), \"not found\") {\n\t\t// already removed: idempotent success\n\t\treturn nil\n\t}\n\treturn err\n}","preventionTips":["Order teardown: RemoveEndpointAddress before RemovePeer","Make peer-removal paths idempotent by treating 'not found' as success","Serialize peer lifecycle mutations to avoid concurrent removal racing endpoint cleanup","Check peer existence via FullStats when operating on stale connection state"],"tags":["wireguard-go","peer-management","idempotency","concurrency","userspace"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}