netbirdio/netbird · error

destroy %s interface: %w

Error message

destroy %s interface: %w

What it means

del() destroys the interface with `ifconfig <name> destroy` and wraps a non-zero exit; ifconfig's stderr is logged at debug level. Common causes: the interface no longer exists (already destroyed by a concurrent path), the interface is busy (routes, addresses, or member-of-bridge references), or insufficient privilege.

Source

Thrown at client/iface/freebsd/link.go:173

	interfaceName, err := parseIFName(output)
	if err != nil {
		return "", fmt.Errorf("parse new name: %w", err)
	}

	return interfaceName, nil
}

func (l *Link) del(name string) error {
	var stderr bytes.Buffer

	cmd := exec.Command("ifconfig", name, "destroy")
	cmd.Stderr = &stderr

	err := cmd.Run()
	if err != nil {
		log.Debugf("ifconfig out: %s", stderr.String())

		return fmt.Errorf("destroy %s interface: %w", name, err)
	}

	return nil
}

func (l *Link) setMTU(mtu int) error {
	var stderr bytes.Buffer

	cmd := exec.Command("ifconfig", l.name, "mtu", strconv.Itoa(mtu))
	cmd.Stderr = &stderr

	if err := cmd.Run(); err != nil {
		log.Debugf("ifconfig out: %s", stderr.String())

		return fmt.Errorf("set interface mtu: %w", err)
	}

	return nil

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Treat a missing interface as success: verify with `ifconfig <name>` first and skip destroy if absent
  2. Flush addresses/routes on the interface before destroy
  3. Ensure a single agent instance owns the interface
  4. Run `sudo ifconfig <name> destroy` by hand to see the exact kernel refusal

Example fix

// before
if err := l.del(name); err != nil {
    return err
}

// after: idempotent teardown
if _, err := net.InterfaceByName(name); err != nil {
    return nil // already gone
}
if err := l.del(name); err != nil {
    return err
}
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := net.InterfaceByName(name); err != nil {
    return nil // interface already gone, nothing to destroy
}

Try / catch

if err := link.Del(); err != nil {
    if _, lerr := net.InterfaceByName(name); lerr != nil {
        return nil // gone: treat as success
    }
    return err
}

Prevention

When it happens

Trigger: Link.Del()/Recreate() when the interface vanished concurrently (double teardown), when addresses or routes still reference it, or when the agent runs unprivileged.

Common situations: Running netbird down twice; a second agent instance already destroyed it; leftover routes keeping the kernel from releasing the interface; jail without interface rights.

Related errors


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