{"record":{"id":"db23da24a599194c","repo":"txthinking/brook","slug":"no-ipv4-from-nic","errorCode":null,"errorMessage":"no ipv4 from nic","messagePattern":"no ipv4 from nic","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/dialwithnic/dialwithnic.go","lineNumber":62,"sourceCode":"\t\tfor _, v := range addrs {\n\t\t\tif v.(*net.IPNet).IP.IsGlobalUnicast() && v.(*net.IPNet).IP.To4() == nil {\n\t\t\t\treturn v.(*net.IPNet).IP, nil\n\t\t\t}\n\t\t}\n\t\treturn nil, errors.New(\"no ipv6 from nic\")\n\t}\n\tif v46 == \"4\" {\n\t\tfor _, v := range addrs {\n\t\t\tif v.(*net.IPNet).IP.IsGlobalUnicast() && !v.(*net.IPNet).IP.IsPrivate() && v.(*net.IPNet).IP.To4() != nil {\n\t\t\t\treturn v.(*net.IPNet).IP, nil\n\t\t\t}\n\t\t}\n\t\tfor _, v := range addrs {\n\t\t\tif v.(*net.IPNet).IP.IsGlobalUnicast() && v.(*net.IPNet).IP.IsPrivate() && v.(*net.IPNet).IP.To4() != nil {\n\t\t\t\treturn v.(*net.IPNet).IP, nil\n\t\t\t}\n\t\t}\n\t\treturn nil, errors.New(\"no ipv4 from nic\")\n\t}\n\treturn nil, errors.New(\"black hole\")\n}\n\nfunc (p *DialWithNIC) TouchBrook() {\n\tbrook.DialTCP = func(network string, laddr, raddr string) (net.Conn, error) {\n\t\tvar la, ra *net.TCPAddr\n\t\tif laddr != \"\" {\n\t\t\tvar err error\n\t\t\tla, err = net.ResolveTCPAddr(network, laddr)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\ta, err := brook.Resolve(network, raddr)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/txthinking/brook/blob/5cd13ef3b1fb574e88ebf2c1b5d95f2ebe1342c8/plugins/dialwithnic/dialwithnic.go#L44-L80","documentation":"In the same IP method, when v46 == \"4\" the code looks for a globally-unicast, PRIVATE IPv4 address (IsPrivate() && To4() != nil) to use as the source. Error [73] means the interface's address list contained no matching private IPv4 address — the host has no private IPv4 address on the selected NIC. The library intentionally wants an RFC1918-style source address and refuses to continue without one.","triggerScenarios":"Calling IP(v46=\"4\") when the enumerated addrs contain no global-unicast private IPv4 address — e.g. the NIC only has IPv6, only a public IPv4 address, or only loopback (127.0.0.1 fails IsGlobalUnicast for the intended use).","commonSituations":"Running in environments where the NIC has only a public IP (some cloud VMs with public IPs directly on the interface); IPv6-only containers; misconfigured interface selection passing the wrong interface's addr list; hosts where the only IPv4 address is loopback.","solutions":["Verify the NIC actually has a private IPv4 address (`ip -4 addr`); if not, add/configure one or pick a different interface whose addr list is passed to IP().","Check the addr-selection/filtering upstream of this loop — if the library lets you choose the NIC, select one with an RFC1918 address.","If a public IPv4 is the only option and fits your use case, bypass the NIC-source constraint and use the default dialer instead of DialWithNIC.","Handle the error as 'no private IPv4 available' and fall back to IPv6 or the default dial path."],"exampleFix":"// before\nip, err := plugin.IP(\"4\") // NIC has only a public IPv4\n// after\nip, err := plugin.IP(\"4\")\nif err != nil {\n    // use default dialer without binding to a private source IP\n    conn, err := net.Dial(\"tcp\", addr)\n}","handlingStrategy":"fallback","validationCode":"func hasPrivateIPv4() bool {\n    for _, a := range interfaceAddrs() {\n        if ipnet, ok := a.(*net.IPNet); ok && ipnet.IP.IsGlobalUnicast() && ipnet.IP.IsPrivate() && ipnet.IP.To4() != nil {\n            return true\n        }\n    }\n    return false\n}\n// only call plugin.IP(\"4\") if hasPrivateIPv4()","typeGuard":"func isPrivateIPv4(ip net.IP) bool {\n    return ip.To4() != nil && ip.IsGlobalUnicast() && ip.IsPrivate()\n}","tryCatchPattern":"ip, err := plugin.IP(\"4\")\nif err != nil && err.Error() == \"no ipv4 from nic\" {\n    log.Println(\"no private IPv4 on NIC, using default dialer\")\n    conn, err = net.Dial(\"tcp\", addr)\n}","preventionTips":["Check `ip -4 addr` / net.InterfaceAddrs() for an RFC1918 address before using DialWithNIC.","Remember the library wants a PRIVATE IPv4 source; a public-only interface will fail — pick a NIC with an internal address.","Avoid relying on this plugin in IPv6-only or public-IP-only environments.","Provide a fallback dial path in callers when source-NIC binding is unavailable."],"tags":["go","network","ipv4","nic"],"backgroundTag":"resource-not-found","analyzedSha":"5cd13ef3b1fb574e88ebf2c1b5d95f2ebe1342c8","analyzedAt":"2026-09-06T04:35:00.432Z","contentChangedAt":"2026-09-06T04:35:00.432Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}