slackhq/nebula · error
could not create netstack NIC: %v
Error message
could not create netstack NIC: %v
What it means
service.New creates a channel-backed NIC in the gVisor netstack via CreateNIC(nicID, linkEP); a non-nil tcpip error aborts startup with this message. Without the NIC there is no link endpoint to route tunneled packets through.
Source
Thrown at service/service.go:84
eg, ctx := errgroup.WithContext(ctx)
s := Service{
eg: eg,
control: control,
}
s.mu.listeners = map[uint16]*tcpListener{}
s.ipstack = stack.New(stack.Options{
NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol},
TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol, udp.NewProtocol, icmp.NewProtocol4, icmp.NewProtocol6},
})
sackEnabledOpt := tcpip.TCPSACKEnabled(true) // TCP SACK is disabled by default
tcpipErr := s.ipstack.SetTransportProtocolOption(tcp.ProtocolNumber, &sackEnabledOpt)
if tcpipErr != nil {
return nil, fmt.Errorf("could not enable TCP SACK: %v", tcpipErr)
}
linkEP := channel.New( /*size*/ 512 /*mtu*/, 1280, "")
if tcpipProblem := s.ipstack.CreateNIC(nicID, linkEP); tcpipProblem != nil {
return nil, fmt.Errorf("could not create netstack NIC: %v", tcpipProblem)
}
ipv4Subnet, _ := tcpip.NewSubnet(tcpip.AddrFrom4([4]byte{0x00, 0x00, 0x00, 0x00}), tcpip.MaskFrom(strings.Repeat("\x00", 4)))
s.ipstack.SetRouteTable([]tcpip.Route{
{
Destination: ipv4Subnet,
NIC: nicID,
},
})
ipNet := device.Networks()
pa := tcpip.ProtocolAddress{
AddressWithPrefix: tcpip.AddrFromSlice(ipNet[0].Addr().AsSlice()).WithPrefix(),
Protocol: ipv4.ProtocolNumber,
}
if err := s.ipstack.AddProtocolAddress(nicID, pa, stack.AddressProperties{
PEB: stack.CanBePrimaryEndpoint, // zero value default
ConfigType: stack.AddressConfigStatic, // zero value default
}); err != nil {View on GitHub (pinned to dd8f660c0a)
Solutions
- Ensure service.New creates its own fresh ipstack and uses the constant nicID only once
- If reusing a stack, pick a unique nicID or call NIC removal/Disable first
- Pin/upgrade the gVisor dependency to match the CreateNIC API this code expects
- Log the wrapped tcpipProblem to identify the exact error (e.g. ErrDuplicateNIC)
Example fix
// before s.ipstack.CreateNIC(nicID, linkEP) // nicID already registered on this stack // after s.ipstack.RemoveNIC(nicID) // or use a fresh stack per service.New s.ipstack.CreateNIC(nicID, linkEP)
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure one NIC per stack: // create a fresh ipstack in service.New; do not share across instances
Try / catch
svc, err := service.New(...)
if err != nil {
if strings.Contains(err.Error(), "netstack NIC") {
log.Fatalf("NIC creation failed (duplicate nicID or gVisor API change): %v", err)
}
return err
} Prevention
- Create one ipstack per service instance; never reuse nicID across New calls
- Upgrade gVisor in lockstep with service code changes
- Surface the wrapped tcpipProblem code in logs
When it happens
Trigger: service.New is called and CreateNIC fails — typically duplicate nicID registration on the same stack, or a gVisor version where channel.New/endpoint registration semantics changed.
Common situations: Calling New twice on the same shared ipstack with the same nicID; custom netstack assembly code reusing nicID; gVisor API mismatch after dependency upgrade.
Related errors
- could not enable TCP SACK: %v
- error creating IP: %s
- unknown network type: %s
- only wildcard address supported, got %q %v
- invalid port %d
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/e0980426ec6283c2.
Report an issue: GitHub.