netbirdio/netbird · error
get device %s: %w
Error message
get device %s: %w
What it means
Inside getPeer, wg.Device(ifaceName) failed. wgctrl returns an error wrapping os.ErrNotExist (ENODEV) when the named interface does not exist or is not a WireGuard device, and other netlink errors for transport problems. It surfaces wrapped as 'get peer: get device <name>: ...' from RemoveAllowedIP and RemoveEndpointAddress.
Source
Thrown at client/iface/configurer/kernel_unix.go:231
}
return nil
}
func (c *KernelConfigurer) getPeer(ifaceName, peerPubKey string) (wgtypes.Peer, error) {
wg, err := wgctrl.New()
if err != nil {
return wgtypes.Peer{}, fmt.Errorf("wgctl: %w", err)
}
defer func() {
err = wg.Close()
if err != nil {
log.Errorf("Got error while closing wgctl: %v", err)
}
}()
wgDevice, err := wg.Device(ifaceName)
if err != nil {
return wgtypes.Peer{}, fmt.Errorf("get device %s: %w", ifaceName, err)
}
for _, peer := range wgDevice.Peers {
if peer.PublicKey.String() == peerPubKey {
return peer, nil
}
}
return wgtypes.Peer{}, ErrPeerNotFound
}
func (c *KernelConfigurer) configure(config wgtypes.Config) error {
wg, err := wgctrl.New()
if err != nil {
return err
}
defer func() {
if err := wg.Close(); err != nil {
log.Errorf("Failed to close wgctrl client: %v", err)
}View on GitHub (pinned to 93e97f4bf1)
Solutions
- Confirm the interface exists and is WireGuard: sudo wg show <deviceName>
- Recreate the interface before reconfiguring peers if it was torn down
- Match on errors.Is(err, os.ErrNotExist) and treat the peer operation as a no-op when the device is gone
- Check for name mismatches when a custom interface name is configured
Defensive patterns
Strategy: validation
Validate before calling
// confirm the interface exists and is a WireGuard device before peer ops
func wgDeviceExists(name string) bool {
if _, err := net.InterfaceByName(name); err != nil {
return false
}
wg, err := wgctrl.New()
if err != nil {
return false
}
defer wg.Close()
_, err = wg.Device(name)
return err == nil
} Try / catch
if err := kernelCfg.RemoveAllowedIP(peerKey, prefix); err != nil {
if errors.Is(err, os.ErrNotExist) {
return nil // device gone: nothing left to configure
}
return err
} Prevention
- Verify the interface with 'wg show <name>' before scripting peer changes
- Recreate the interface before reconfiguring peers after teardown
- Use one constant for the interface name across creation and configuration
- Drop configurer instances when the interface is deleted; never reuse them
When it happens
Trigger: Interface name typo or renamed device; interface deleted before the peer lookup; device exists but was created by a non-WireGuard driver; netlink transport error mid-query.
Common situations: NetBird interface (default wt0) already torn down when a route removal runs; custom interface name configured inconsistently between creation and configurer; agents in environments where another tool removed the link.
Related errors
- received error "%w" while adding allowed Ip to peer on inter
- received error "%w" while configuring interface %s with port
- received error "%w" while updating peer on interface %s with
- received error "%w" while removing peer %s from interface %s
- remove allowed IP %s on interface %s: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/955c3718ae458878.
Report an issue: GitHub.