netbirdio/netbird · warning

remove windows v6 firewall rule: %w

Error message

remove windows v6 firewall rule: %w

What it means

Appended to the same multierror in allow_netbird_windows.go:43 when deleting the IPv6 variant rule ('<name>-v6') via netsh fails. Identical failure surface to the v4 rule (elevation, service state, policy), plus IPv6-specific cases: IPv6 networking support disabled on the host can make the v6 rule unqueryable or undeletable even though isFirewallRuleActive saw it.

Source

Thrown at client/firewall/uspfilter/allow_netbird_windows.go:43

	m.mutex.Lock()
	defer m.mutex.Unlock()

	m.resetState()

	if !isWindowsFirewallReachable() {
		return nil
	}

	var merr *multierror.Error
	if isFirewallRuleActive(firewallRuleName) {
		if err := manageFirewallRule(firewallRuleName, deleteRule); err != nil {
			merr = multierror.Append(merr, fmt.Errorf("remove windows firewall rule: %w", err))
		}
	}

	if isFirewallRuleActive(firewallRuleName + "-v6") {
		if err := manageFirewallRule(firewallRuleName+"-v6", deleteRule); err != nil {
			merr = multierror.Append(merr, fmt.Errorf("remove windows v6 firewall rule: %w", err))
		}
	}

	return nberrors.FormatErrorOrNil(merr)
}

// AllowNetbird allows netbird interface traffic
func (m *Manager) AllowNetbird() error {
	if !isWindowsFirewallReachable() {
		return nil
	}

	if !isFirewallRuleActive(firewallRuleName) {
		if err := manageFirewallRule(firewallRuleName,
			addRule,
			"dir=in",
			"enable=yes",
			"action=allow",

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Run elevated and verify with 'netsh advfirewall firewall show rule name=<name>-v6' then delete manually to see the true error
  2. Ensure IPv6 is enabled on the host if the v6 rule must be managed
  3. If IPv6 is intentionally disabled, treat the v6 deletion failure as benign - the rule is inert without an IPv6 stack
  4. Retry Reset once after firewall services stabilize; the multierror already keeps the v4 result independent
Defensive patterns

Strategy: try-catch

Validate before calling

if !isWindowsFirewallReachable() {
    return nil
}
if !ipv6EnabledOnHost() {
    // v6 rule is inert without the IPv6 stack
    return nil
}

Type guard

func ipv6EnabledOnHost() bool {
    ifaces, err := net.Interfaces()
    if err != nil {
        return false
    }
    for _, i := range ifaces {
        addrs, err := i.Addrs()
        if err != nil {
            continue
        }
        for _, a := range addrs {
            if ipnet, ok := a.(*net.IPNet); ok && ipnet.IP.To16() != nil && ipnet.IP.To4() == nil {
                return true
            }
        }
    }
    return false
}

Try / catch

if err := manager.Reset(nil); err != nil {
    if strings.Contains(err.Error(), "v6 firewall rule") {
        log.Warn("v6 firewall rule left behind; IPv6 disabled or policy-locked host")
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: Non-elevated Reset; Windows Firewall service flapping between the show and delete calls; IPv6 stack disabled via registry/adapter settings after the rule was created; group policy locking per-profile rules including the v6 one.

Common situations: Hardened Windows images with IPv6 disabled; mismatched rule versions after an agent upgrade that renamed the v6 rule; security software blocking netsh mutations.

Related errors


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