netbirdio/netbird · error

get IPC config: %w

Error message

get IPC config: %w

What it means

WGUSPConfigurer.RemoveEndpointAddress could not read the current configuration from the in-process wireguard-go device via device.IpcGet(). The dump is needed to preserve the peer's allowed IPs across the remove/re-add cycle that clears the endpoint. IpcGet fails chiefly when the device is closed or its state is torn down mid-call, since the configurer and the wireguard-go device share one process lifetime.

Source

Thrown at client/iface/configurer/usp.go:140

		addr, err := netip.ParseAddr(endpoint.IP.String())
		if err != nil {
			return fmt.Errorf("failed to parse endpoint address: %w", err)
		}
		addrPort := netip.AddrPortFrom(addr.Unmap(), uint16(endpoint.Port))
		c.activityRecorder.UpsertAddress(peerKey, addrPort)
	}
	return nil
}

func (c *WGUSPConfigurer) RemoveEndpointAddress(peerKey string) error {
	peerKeyParsed, err := wgtypes.ParseKey(peerKey)
	if err != nil {
		return fmt.Errorf("parse peer key: %w", err)
	}

	ipcStr, err := c.device.IpcGet()
	if err != nil {
		return fmt.Errorf("get IPC config: %w", err)
	}

	// Parse current status to get allowed IPs for the peer
	stats, err := parseStatus(c.deviceName, ipcStr)
	if err != nil {
		return fmt.Errorf("parse IPC config: %w", err)
	}

	var allowedIPs []net.IPNet
	found := false
	for _, peer := range stats.Peers {
		if peer.PublicKey == peerKey {
			allowedIPs = peer.AllowedIPs
			found = true
			break
		}
	}
	if !found {

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Order teardown: clear peer endpoints before closing the wireguard-go device
  2. Check whether the device is already closed and skip endpoint cleanup then
  3. Retry once after the device is confirmed running
  4. Log the raw IpcGet error to distinguish 'closed' from serialization failures
Defensive patterns

Strategy: try-catch

Try / catch

if err := uspCfg.RemoveEndpointAddress(peerKey); err != nil {
	if strings.Contains(err.Error(), "get IPC config") {
		// device likely closed: verify lifecycle before retrying
		return fmt.Errorf("device state unreadable; is the device closed? %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: RemoveEndpointAddress invoked after the wireguard-go device was Closed; Close racing the call; device in a half-initialized state after a failed ConfigureInterface.

Common situations: Teardown ordering bugs where connection cleanup runs after iface Close; reconnect flow rebuilding the device while stale peer handlers still fire; embedded/netstack clients tearing down quickly.

Related errors


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