{"record":{"id":"1e00cb1b9c518a25","repo":"netbirdio/netbird","slug":"creating-default-v6-subnet-w","errorCode":null,"errorMessage":"creating default v6 subnet: %w","messagePattern":"creating default v6 subnet: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"client/firewall/uspfilter/forwarder/forwarder.go","lineNumber":125,"sourceCode":"\t\tif err := s.AddProtocolAddress(nicID, v6Addr, stack.AddressProperties{}); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"add IPv6 protocol address: %s\", err)\n\t\t}\n\t}\n\n\tdefaultSubnet, err := tcpip.NewSubnet(\n\t\ttcpip.AddrFrom4([4]byte{0, 0, 0, 0}),\n\t\ttcpip.MaskFromBytes([]byte{0, 0, 0, 0}),\n\t)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"creating default subnet: %w\", err)\n\t}\n\n\tdefaultSubnetV6, err := tcpip.NewSubnet(\n\t\ttcpip.AddrFrom16([16]byte{}),\n\t\ttcpip.MaskFromBytes(make([]byte, 16)),\n\t)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"creating default v6 subnet: %w\", err)\n\t}\n\n\tif err := s.SetPromiscuousMode(nicID, true); err != nil {\n\t\treturn nil, fmt.Errorf(\"set promiscuous mode: %s\", err)\n\t}\n\tif err := s.SetSpoofing(nicID, true); err != nil {\n\t\treturn nil, fmt.Errorf(\"set spoofing: %s\", err)\n\t}\n\n\ts.SetRouteTable([]tcpip.Route{\n\t\t{Destination: defaultSubnet, NIC: nicID},\n\t\t{Destination: defaultSubnetV6, NIC: nicID},\n\t})\n\n\tctx, cancel := context.WithCancel(context.Background())\n\tf := &Forwarder{\n\t\tlogger:        logger,\n\t\tflowLogger:    flowLogger,","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/firewall/uspfilter/forwarder/forwarder.go#L107-L143","documentation":"Returned when tcpip.NewSubnet rejects the default IPv6 catch-all ::/0. Like its IPv4 twin, NewSubnet only errors on a non-contiguous mask, and the code passes a literal 16-zero-byte mask, so with the constants as written this branch is unreachable defensive error handling.","triggerScenarios":"Only possible if the hardcoded make([]byte, 16) mask is replaced by computed bytes with holes in it, or gVisor's NewSubnet semantics change between versions.","commonSituations":"Not observed in practice; a developer who copies this constructor and derives the mask from a variable (e.g. a user-supplied prefix) can trigger it with an invalid mask.","solutions":["No action needed for the literal form","If the mask becomes computed, construct it exclusively via tcpip.MaskFromBits(prefixLen) with prefixLen validated to 0..128","Verify gVisor version compatibility after upgrades if this ever fires"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"f, err := forwarder.New(iface, logger, flowLogger, netstack, mtu)\nif err != nil {\n    log.Errorf(\"forwarder init failed: %v\", err)\n    return err\n}","preventionTips":["Keep the ::/0 mask as literal zero bytes","Derive any computed mask exclusively via tcpip.MaskFromBits with a validated prefix length"],"tags":["go","netbird","gvisor","netstack","ipv6","defensive"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}