netbirdio/netbird · error

received error "%w" while updating peer on interface %s with

Error message

received error "%w" while updating peer on interface %s with settings: allowed ips %s, endpoint %s

What it means

The kernel configurer failed to push a peer update (allowed IPs, endpoint, keepalive, preshared key) to the WireGuard device. The underlying c.configure error comes from wgctrl/netlink and is almost always device-missing (ENOENT after the interface was removed), permission loss, or a malformed field such as an unparseable endpoint or an allowed-IP netmask the kernel rejects. The message includes the peer's allowed IPs and endpoint to make misconfigured peer data identifiable.

Source

Thrown at client/iface/configurer/kernel_unix.go:84

	if err != nil {
		return err
	}
	peer := wgtypes.PeerConfig{
		PublicKey:         peerKeyParsed,
		ReplaceAllowedIPs: false,
		// don't replace allowed ips, wg will handle duplicated peer IP
		AllowedIPs:                  prefixesToIPNets(allowedIps),
		PersistentKeepaliveInterval: &keepAlive,
		Endpoint:                    endpoint,
		PresharedKey:                preSharedKey,
	}

	config := wgtypes.Config{
		Peers: []wgtypes.PeerConfig{peer},
	}
	err = c.configure(config)
	if err != nil {
		return fmt.Errorf(`received error "%w" while updating peer on interface %s with settings: allowed ips %s, endpoint %s`, err, c.deviceName, allowedIps, endpoint.String())
	}
	return nil
}

func (c *KernelConfigurer) RemoveEndpointAddress(peerKey string) error {
	peerKeyParsed, err := wgtypes.ParseKey(peerKey)
	if err != nil {
		return err
	}

	// Get the existing peer to preserve its allowed IPs
	existingPeer, err := c.getPeer(c.deviceName, peerKey)
	if err != nil {
		return fmt.Errorf("get peer: %w", err)
	}

	removePeerCfg := wgtypes.PeerConfig{
		PublicKey: peerKeyParsed,

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Read the wrapped cause: device ENOENT points to a lifecycle race, EINVAL to bad peer data, EACCES to privileges
  2. Log the allowed IPs and endpoint from the message and cross-check the peer entry in the management network map for family/mask errors
  3. Serialize peer updates with interface bring-up/teardown so updates never target a half-dead device
  4. Verify the process still holds root/CAP_NET_ADMIN
  5. Retry the update after the interface is confirmed present
Defensive patterns

Strategy: try-catch

Validate before calling

// validate peer data before pushing it to the kernel
for _, pfx := range allowedIps {
    if !pfx.IsValid() || (pfx.Addr().Is4() && pfx.Bits() > 32) {
        return fmt.Errorf("bad allowed IP %s", pfx)
    }
}
if endpoint != nil && endpoint.Port() == 0 {
    return errors.New("peer endpoint has no port")
}

Type guard

func peerConfigValid(allowedIps []netip.Prefix, endpoint *net.UDPAddr) bool {
    if endpoint != nil && (endpoint.Port == 0 || endpoint.IP == nil) {
        return false
    }
    for _, p := range allowedIps {
        if !p.IsValid() {
            return false
        }
    }
    return true
}

Try / catch

if err := configurer.UpdatePeer(peerKey, allowedIps, endpoint, keepAlive, psk); err != nil {
    if errors.Is(err, syscall.ENOENT) {
        // device gone: re-run interface bring-up, then retry the update once
    }
    return fmt.Errorf("update peer %s: %w", peerKey, err)
}

Prevention

When it happens

Trigger: Updating a peer on an interface that was concurrently deleted or recreated; endpoint host/port invalid or unreachable at the netlink validation layer; an allowed-IPs entry with a mask that does not match the address family; running without CAP_NET_ADMIN so the update is refused.

Common situations: Network map updates arriving while the engine restarts the interface (login, address change, IPv6 toggle); a peer in the management network map carrying a malformed endpoint; agents in restricted containers; version skew where a newer management sends data older wgctrl validates differently.

Related errors


AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16). Data as JSON: /api/errors/a389983e04e2cf66. Report an issue: GitHub.