{"record":{"id":"f2eab06a472c432f","repo":"netbirdio/netbird","slug":"decode-peerid-w","errorCode":null,"errorMessage":"decode peerID: %w","messagePattern":"decode peerID: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"client/iface/configurer/usp.go","lineNumber":384,"sourceCode":"\nfunc parseTransfers(ipc string) (map[string]WGStats, error) {\n\tstats := make(map[string]WGStats)\n\tvar (\n\t\tcurrentKey   string\n\t\tcurrentStats WGStats\n\t\thasPeer      bool\n\t)\n\tlines := strings.Split(ipc, \"\\n\")\n\tfor _, line := range lines {\n\t\tline = strings.TrimSpace(line)\n\n\t\t// If we're within the details of the found peer and encounter another public key,\n\t\t// this means we're starting another peer's details. So, stop.\n\t\tif strings.HasPrefix(line, \"public_key=\") {\n\t\t\tpeerID := strings.TrimPrefix(line, \"public_key=\")\n\t\t\th, err := hex.DecodeString(peerID)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"decode peerID: %w\", err)\n\t\t\t}\n\t\t\tcurrentKey = base64.StdEncoding.EncodeToString(h)\n\t\t\tcurrentStats = WGStats{} // Reset stats for the new peer\n\t\t\thasPeer = true\n\t\t\tstats[currentKey] = currentStats\n\t\t\tcontinue\n\t\t}\n\n\t\tif !hasPeer {\n\t\t\tcontinue\n\t\t}\n\n\t\tkey := strings.SplitN(line, \"=\", 2)\n\t\tif len(key) != 2 {\n\t\t\tcontinue\n\t\t}\n\t\tswitch key[0] {\n\t\tcase ipcKeyLastHandshakeTimeSec:","sourceCodeStart":366,"sourceCodeEnd":402,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/iface/configurer/usp.go#L366-L402","documentation":"parseTransfers, which turns a wireguard-go IpcGet dump into per-peer stats, failed to hex-decode the value of a public_key= line with hex.DecodeString. The wireguard-go UAPI always emits public keys as 64 lowercase hex characters, so this only fires when the dump is malformed, comes from an incompatible producer, or was corrupted. The decoded bytes are re-encoded to base64 to key the stats map.","triggerScenarios":"An IPC string not produced by the paired wireguard-go device (hand-crafted test input, foreign implementation); truncated or whitespace-padded public_key line; memory corruption of the dumped string.","commonSituations":"Unit tests feeding synthetic IPC strings with wrong key formats; a vendored wireguard-go fork emitting base64 keys; version skew after upgrading the wireguard-go dependency.","solutions":["Validate the producer: only pass IpcGet output from the matching wireguard-go device","Skip unparseable public_key lines (log at debug) rather than failing the whole stats fetch","Pin the wireguard-go version and add a fixture test for the dump format","Check the raw dump for truncation when this appears in logs"],"exampleFix":"// before\nh, err := hex.DecodeString(peerID)\nif err != nil {\n\treturn nil, fmt.Errorf(\"decode peerID: %w\", err)\n}\n\n// after: skip malformed keys instead of dropping all stats\nh, err := hex.DecodeString(peerID)\nif err != nil {\n\tlog.Debugf(\"skipping malformed public_key line: %v\", err)\n\tcontinue\n}","handlingStrategy":"type-guard","validationCode":"// sanity-check a UAPI public_key line before relying on it\nfunc validPublicKeyLine(line string) bool {\n\tv := strings.TrimPrefix(line, \"public_key=\")\n\treturn len(v) == 64\n}","typeGuard":"func isHexPeerID(s string) bool {\n\tif len(s) != 64 {\n\t\treturn false\n\t}\n\t_, err := hex.DecodeString(s)\n\treturn err == nil\n}","tryCatchPattern":"stats, err := uspCfg.GetStats()\nif err != nil {\n\tif strings.Contains(err.Error(), \"decode peerID\") {\n\t\t// malformed/foreign IPC dump: log and return partial stats rather than failing\n\t\tlog.Warnf(\"stats parse hit malformed peer key: %v\", err)\n\t\treturn map[string]configurer.WGStats{}, nil\n\t}\n\treturn nil, err\n}","preventionTips":["Only feed IpcGet output from the paired wireguard-go version into stats parsing","Skip malformed public_key lines instead of failing the entire stats fetch","Pin the wireguard-go dependency and fixture-test its UAPI format","Log dump length and offending line when hex decoding fails"],"tags":["wireguard-go","uapi","hex","parsing","stats"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}