{"record":{"id":"3020eded88cac40f","repo":"netbirdio/netbird","slug":"parse-peer-key-w-3020ed","errorCode":null,"errorMessage":"parse peer key: %w","messagePattern":"parse peer key: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/iface/configurer/usp.go","lineNumber":135,"sourceCode":"\tif ipcErr := c.device.IpcSet(toWgUserspaceString(config)); ipcErr != nil {\n\t\treturn ipcErr\n\t}\n\n\tif endpoint != nil {\n\t\taddr, err := netip.ParseAddr(endpoint.IP.String())\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to parse endpoint address: %w\", err)\n\t\t}\n\t\taddrPort := netip.AddrPortFrom(addr.Unmap(), uint16(endpoint.Port))\n\t\tc.activityRecorder.UpsertAddress(peerKey, addrPort)\n\t}\n\treturn nil\n}\n\nfunc (c *WGUSPConfigurer) RemoveEndpointAddress(peerKey string) error {\n\tpeerKeyParsed, err := wgtypes.ParseKey(peerKey)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"parse peer key: %w\", err)\n\t}\n\n\tipcStr, err := c.device.IpcGet()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"get IPC config: %w\", err)\n\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","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/iface/configurer/usp.go#L117-L153","documentation":"WGUSPConfigurer.RemoveEndpointAddress could not parse the peer key with wgtypes.ParseKey, which requires a base64-encoded 32-byte key string. Any other encoding (notably the hex form used in wireguard-go UAPI lines), truncation, whitespace, or an empty string fails here before the IPC dump is read. It is the userspace twin of the parse error in the kernel configurer's RemoveAllowedIP.","triggerScenarios":"Hex-encoded peer key passed where base64 is expected; key copied from a public_key=<hex> UAPI line; empty or truncated key from an upstream payload; whitespace or newline appended to the key.","commonSituations":"Sharing key strings between kernel-mode and userspace-mode code paths without format conversion; management or test fixtures supplying malformed keys; keys logged and re-read with formatting artifacts.","solutions":["Validate once at ingestion with wgtypes.ParseKey and store key.String()","Convert hex keys explicitly via hex.DecodeString + wgtypes.NewKey","Trim whitespace and reject empty keys at the boundary that produces peer keys"],"exampleFix":"// before\nerr := cfg.RemoveEndpointAddress(hexKey)\n\n// after\nb, err := hex.DecodeString(hexKey)\nif err != nil {\n\treturn err\n}\nk, err := wgtypes.NewKey(b)\nif err != nil {\n\treturn err\n}\nerr = cfg.RemoveEndpointAddress(k.String())","handlingStrategy":"validation","validationCode":"// normalize the key before calling into the userspace configurer\nparsed, err := wgtypes.ParseKey(peerKey)\nif err != nil {\n\treturn fmt.Errorf(\"bad peer key from upstream: %w\", err)\n}\nreturn uspCfg.RemoveEndpointAddress(parsed.String())","typeGuard":"func isValidWGPeerKey(s string) bool {\n\t_, err := wgtypes.ParseKey(s)\n\treturn err == nil\n}","tryCatchPattern":"if err := uspCfg.RemoveEndpointAddress(peerKey); err != nil {\n\tif _, perr := wgtypes.ParseKey(peerKey); perr != nil {\n\t\t// producer bug: fix key format at source, retrying will not help\n\t\treturn fmt.Errorf(\"peer key malformed upstream: %w\", perr)\n\t}\n\treturn err\n}","preventionTips":["Accept only wgtypes.Key.String() output as the canonical peer-key format in your code","Convert hex keys at the UAPI boundary, never inside configurer calls","Fuzz-test key ingestion with the exact formats your producers emit","Fail fast on malformed keys at ingress with a clear log of the offending length"],"tags":["wireguard","key-parsing","base64","userspace","validation"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}