{"record":{"id":"225c0a82c84895fa","repo":"netbirdio/netbird","slug":"decode-v6-overlay-address-w","errorCode":null,"errorMessage":"decode v6 overlay address: %w","messagePattern":"decode v6 overlay address: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/iface/wgaddr/address.go","lineNumber":72,"sourceCode":"// IPv6Prefix returns the v6 host address with its network prefix length, or a zero prefix if none.\nfunc (addr Address) IPv6Prefix() netip.Prefix {\n\tif !addr.HasIPv6() {\n\t\treturn netip.Prefix{}\n\t}\n\treturn netip.PrefixFrom(addr.IPv6, addr.IPv6Net.Bits())\n}\n\n// SetIPv6FromCompact decodes a compact prefix (5 or 17 bytes) and sets the IPv6 fields.\n// Returns an error if the bytes are invalid. A nil or empty input is a no-op.\n//\n//nolint:recvcheck\nfunc (addr *Address) SetIPv6FromCompact(raw []byte) error {\n\tif len(raw) == 0 {\n\t\treturn nil\n\t}\n\tprefix, err := netiputil.DecodePrefix(raw)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"decode v6 overlay address: %w\", err)\n\t}\n\tif !prefix.Addr().Is6() {\n\t\treturn fmt.Errorf(\"expected IPv6 address, got %s\", prefix.Addr())\n\t}\n\taddr.IPv6 = prefix.Addr()\n\taddr.IPv6Net = prefix.Masked()\n\treturn nil\n}\n\n// ClearIPv6 removes the IPv6 overlay address, leaving only v4.\n//\n//nolint:recvcheck\nfunc (addr *Address) ClearIPv6() {\n\taddr.IPv6 = netip.Addr{}\n\taddr.IPv6Net = netip.Prefix{}\n}\n","sourceCodeStart":54,"sourceCodeEnd":89,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/iface/wgaddr/address.go#L54-L89","documentation":"Address.SetIPv6FromCompact decodes a compact prefix (5 or 17 bytes) via netiputil.DecodePrefix and applies it to the IPv6 fields. This error wraps the decode failure: wrong byte length, invalid embedded prefix length, or otherwise malformed bytes. Nil or empty input is a documented no-op and never errors; a decoded non-IPv6 result fails the separate Is6 check instead.","triggerScenarios":"Decoding the compact IPv6 network bytes received from the management network map or read from stored state when they are truncated, sized for a different version of the format, or corrupt.","commonSituations":"Management and agent version mismatch on the compact v6 format; corrupted persisted state after an unclean shutdown; a peer or setup flow writing wrong-length bytes into the field.","solutions":["Validate the byte length before decoding (empty, 5, or 17 bytes for the compact encoding)","Confirm management and agent run compatible versions of the network map format","Re-register the peer (netbird down/up) to fetch a fresh network map","If it persists, inspect the stored state or protobuf payload for corruption"],"exampleFix":"// before\nvar a wgaddr.Address\nif err := a.SetIPv6FromCompact(raw); err != nil {\n    return err\n}\n\n// after\nif n := len(raw); n != 0 && n != 5 && n != 17 {\n    return fmt.Errorf(\"invalid compact prefix length %d\", n)\n}\nif err := a.SetIPv6FromCompact(raw); err != nil {\n    return err\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func isValidCompactPrefix(raw []byte) bool {\n    n := len(raw)\n    return n == 0 || n == 5 || n == 17\n}","tryCatchPattern":"if err := addr.SetIPv6FromCompact(raw); err != nil {\n    log.Warnf(\"ignoring malformed v6 overlay address: %v\", err)\n    addr.ClearIPv6() // keep the IPv4 path alive\n}","preventionTips":["Pin length checks (0, 5, or 17 bytes) before decoding","Keep management and agent versions aligned on the compact prefix format","Treat v6 decode failure as soft: clear v6 and continue with v4 only"],"tags":["go","netbird","ipv6","encoding","network-map"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}