netbirdio/netbird · error
received error "%w" while configuring interface %s with port
Error message
received error "%w" while configuring interface %s with port %d
What it means
The kernel WireGuard configurer failed to apply the device-level configuration (private key, fwmark, listen port) through wgctrl/netlink on the named interface. The %w chain carries the underlying cause, which in practice is syscall.ENOENT when the interface disappeared, EACCES/EPERM without CAP_NET_ADMIN or root, EADDRINUSE when the listen port is taken, or EINVAL for a bad key/fwmark. The message deliberately names the interface and port because the same error covers several distinct root causes.
Source
Thrown at client/iface/configurer/kernel_unix.go:47
}
func (c *KernelConfigurer) ConfigureInterface(privateKey string, port int) error {
log.Debugf("adding Wireguard private key")
key, err := wgtypes.ParseKey(privateKey)
if err != nil {
return err
}
fwmark := getFwmark()
config := wgtypes.Config{
PrivateKey: &key,
ReplacePeers: true,
FirewallMark: &fwmark,
ListenPort: &port,
}
err = c.configure(config)
if err != nil {
return fmt.Errorf(`received error "%w" while configuring interface %s with port %d`, err, c.deviceName, port)
}
return nil
}
// SetPresharedKey sets the preshared key for a peer.
// If updateOnly is true, only updates the existing peer; if false, creates or updates.
func (c *KernelConfigurer) SetPresharedKey(peerKey string, psk wgtypes.Key, updateOnly bool) error {
parsedPeerKey, err := wgtypes.ParseKey(peerKey)
if err != nil {
return err
}
cfg := buildPresharedKeyConfig(parsedPeerKey, psk, updateOnly)
return c.configure(cfg)
}
func (c *KernelConfigurer) UpdatePeer(peerKey string, allowedIps []netip.Prefix, keepAlive time.Duration, endpoint *net.UDPAddr, preSharedKey *wgtypes.Key) error {
peerKeyParsed, err := wgtypes.ParseKey(peerKey)View on GitHub (pinned to 93e97f4bf1)
Solutions
- Check the wrapped syscall: ENOENT means recreate the interface first; EACCES means run privileged; EADDRINUSE means change the port or free it
- Verify the agent runs as root or with CAP_NET_ADMIN (container: --cap-add NET_ADMIN)
- Ensure only one agent instance manages the interface and previous runs fully tore it down (netbird down / ip link del)
- Retry the configure once after recreating the interface when the cause is the teardown race
- On port conflicts, let NetBird pick an ephemeral port instead of pining ListenPort
Example fix
// before
if err := c.Configure(key, port); err != nil { return err }
// after
if err := c.Configure(key, port); err != nil {
if errors.Is(err, syscall.ENOENT) {
// interface vanished; caller recreates it and retries once
return fmt.Errorf("interface %s gone, recreate: %w", c.deviceName, err)
}
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
// before configuring, confirm privileges and interface presence
if os.Geteuid() != 0 {
return errors.New("kernel WireGuard configuration requires root")
}
if _, err := net.InterfaceByName(ifaceName); err != nil {
return fmt.Errorf("interface missing, recreate first: %w", err)
} Type guard
func kernelWGReady(name string) bool {
if _, err := net.InterfaceByName(name); err != nil {
return false
}
client, err := wgctrl.New()
if err != nil {
return false
}
defer client.Close()
_, err = client.Device(name)
return err == nil
} Try / catch
if err := configurer.ConfigureInterface(key, port); err != nil {
switch {
case errors.Is(err, syscall.ENOENT):
// recreate interface and retry once
case errors.Is(err, syscall.EADDRINUSE):
// pick a different listen port
case errors.Is(err, syscall.EACCES), errors.Is(err, syscall.EPERM):
return fmt.Errorf("need root/CAP_NET_ADMIN: %w", err)
default:
return err
}
} Prevention
- Run the agent as root or with CAP_NET_ADMIN (containers: --cap-add NET_ADMIN)
- Ensure the previous instance fully tore the interface down before a new one configures it
- Avoid pinning ListenPort unless required; ephemeral ports dodge EADDRINUSE
- Retry once on ENOENT: the delete/configure race is common during rapid restarts
When it happens
Trigger: The interface was deleted between creation and configuration (race with teardown or external ip link del); agent not running as root or missing CAP_NET_ADMIN; the requested ListenPort already bound by another process; wgctrl kernel socket unavailable in restricted containers/seccomp profiles.
Common situations: Running netbird without privileges or in a container lacking NET_ADMIN; another WireGuard instance or the previous unclean shutdown still holding the port; platform uapi/wgctrl regressions after kernel or package upgrades; interface churn during rapid up/down cycles.
Related errors
- received error "%w" while updating peer on interface %s with
- received error "%w" while removing peer %s from interface %s
- get peer: %w
- error removing peer %s from interface %s: %w
- error re-adding peer %s to interface %s with allowed IPs %v:
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/b0e8575864105af2.
Report an issue: GitHub.