netbirdio/netbird · info
creating default v6 subnet: %w
Error message
creating default v6 subnet: %w
What it means
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.
Source
Thrown at client/firewall/uspfilter/forwarder/forwarder.go:125
if err := s.AddProtocolAddress(nicID, v6Addr, stack.AddressProperties{}); err != nil {
return nil, fmt.Errorf("add IPv6 protocol address: %s", err)
}
}
defaultSubnet, err := tcpip.NewSubnet(
tcpip.AddrFrom4([4]byte{0, 0, 0, 0}),
tcpip.MaskFromBytes([]byte{0, 0, 0, 0}),
)
if err != nil {
return nil, fmt.Errorf("creating default subnet: %w", err)
}
defaultSubnetV6, err := tcpip.NewSubnet(
tcpip.AddrFrom16([16]byte{}),
tcpip.MaskFromBytes(make([]byte, 16)),
)
if err != nil {
return nil, fmt.Errorf("creating default v6 subnet: %w", err)
}
if err := s.SetPromiscuousMode(nicID, true); err != nil {
return nil, fmt.Errorf("set promiscuous mode: %s", err)
}
if err := s.SetSpoofing(nicID, true); err != nil {
return nil, fmt.Errorf("set spoofing: %s", err)
}
s.SetRouteTable([]tcpip.Route{
{Destination: defaultSubnet, NIC: nicID},
{Destination: defaultSubnetV6, NIC: nicID},
})
ctx, cancel := context.WithCancel(context.Background())
f := &Forwarder{
logger: logger,
flowLogger: flowLogger,View on GitHub (pinned to 93e97f4bf1)
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
Defensive patterns
Strategy: try-catch
Try / catch
f, err := forwarder.New(iface, logger, flowLogger, netstack, mtu)
if err != nil {
log.Errorf("forwarder init failed: %v", err)
return err
} Prevention
- Keep the ::/0 mask as literal zero bytes
- Derive any computed mask exclusively via tcpip.MaskFromBits with a validated prefix length
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- add IPv6 protocol address: %s
- creating default subnet: %w
- set promiscuous mode: %s
- set spoofing: %s
- create IPv6 firewall: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/1e00cb1b9c518a25.
Report an issue: GitHub.