{"record":{"id":"83f29fc1ee7e382f","repo":"netbirdio/netbird","slug":"build-packet-w","errorCode":null,"errorMessage":"build packet: %w","messagePattern":"build packet: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/firewall/uspfilter/tracer.go","lineNumber":264,"sourceCode":"\tswitch protocol {\n\tcase fw.ProtocolTCP:\n\t\treturn layers.IPProtocolTCP\n\tcase fw.ProtocolUDP:\n\t\treturn layers.IPProtocolUDP\n\tcase fw.ProtocolICMP:\n\t\tif isV6 {\n\t\t\treturn layers.IPProtocolICMPv6\n\t\t}\n\t\treturn layers.IPProtocolICMPv4\n\tdefault:\n\t\treturn 0\n\t}\n}\n\nfunc (m *Manager) TracePacketFromBuilder(builder *PacketBuilder) (*PacketTrace, error) {\n\tpacketData, err := builder.Build()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"build packet: %w\", err)\n\t}\n\n\treturn m.TracePacket(packetData, builder.Direction), nil\n}\n\nfunc (m *Manager) TracePacket(packetData []byte, direction fw.RuleDirection) *PacketTrace {\n\n\td := m.decoders.Get().(*decoder)\n\tdefer m.decoders.Put(d)\n\n\ttrace := &PacketTrace{Direction: direction}\n\n\t// Initial packet decoding\n\tif err := d.decodePacket(packetData); err != nil {\n\t\ttrace.AddResult(StageReceived, fmt.Sprintf(\"Failed to decode packet: %v\", err), false)\n\t\treturn trace\n\t}\n","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/firewall/uspfilter/tracer.go#L246-L282","documentation":"TracePacketFromBuilder wraps any failure from PacketBuilder.Build, which itself aggregates the earlier builder errors: mixed address families in buildIPLayer, checksum network-layer mismatch in the TCP/UDP builders, or SerializeLayers failures (length overflow, unencodable layer state). This is the single error surface a caller of the trace API sees, so the underlying cause is only visible in the wrapped chain.","triggerScenarios":"Calling TracePacketFromBuilder with a PacketBuilder whose SrcIP/DstIP families differ or one is unset; PayloadSize beyond the 16-bit length limits; an ICMPv6 trace where the network-layer assertion failed; any refactor that breaks the ipLayer/transportLayer pairing.","commonSituations":"Building trace/diagnostics tooling on uspfilter and constructing PacketBuilder values from user or config input without prior normalization; automated tests sweeping address families and payload sizes and hitting an unhandled combination.","solutions":["Inspect errors.Is/errors.Unwrap on the returned error to find which builder stage failed (family, checksum, or serialize)","Validate before calling: both IPs valid and same-family, ports set, PayloadSize bounded","Normalize addresses with Unmap() at ingestion so v4-mapped v6 does not sneak into the family check","Add per-protocol happy-path tests so regressions surface as specific builder errors, not this generic wrap"],"exampleFix":"// before\ntrace, err := m.TracePacketFromBuilder(b)\n\n// after\nif err := b.Validate(); err != nil { // same-family + bounds checks\n    return nil, err\n}\ntrace, err := m.TracePacketFromBuilder(b)\nif err != nil {\n    return nil, fmt.Errorf(\"trace packet: %w\", err)\n}","handlingStrategy":"try-catch","validationCode":"if !p.SrcIP.IsValid() || !p.DstIP.IsValid() || p.SrcIP.Is4() != p.DstIP.Is4() {\n    return errors.New(\"packet builder inputs invalid\")\n}\nif p.PayloadSize > 0xffff-28 {\n    return errors.New(\"payload too large\")\n}\ntrace, err := m.TracePacketFromBuilder(p)","typeGuard":"func traceInputsValid(p *PacketBuilder) bool {\n    return p.SrcIP.IsValid() && p.DstIP.IsValid() &&\n        p.SrcIP.Is4() == p.DstIP.Is4() && sanePayloadSize(p.PayloadSize)\n}","tryCatchPattern":"trace, err := m.TracePacketFromBuilder(b)\nif err != nil {\n    // unwrap to classify: family / checksum / serialize, then fix inputs and rebuild\n    log.Debugf(\"trace build failed: %v\", err)\n    return nil, err\n}","preventionTips":["Validate builder inputs at your tool's entry point, closest to the user input","Unwrap the error chain before deciding retry vs fail: only input errors are deterministic","Keep one code path that constructs PacketBuilder so validation lives in one place"],"tags":["go","netbird","tracer","gopacket","wrapper"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}