netbirdio/netbird · warning

reset v6 acl manager: %w

Error message

reset v6 acl manager: %w

What it means

During Manager.Close, aclMgr6.Reset() failed - removing the v6 ACL chains (NETBIRD-ACL-INPUT), optional mangle entries, and v6 ipsets. The error is accumulated into the multierror and the remaining steps (v6 router, v4 acl, v4 router) still run; the persisted ShutdownState is deliberately kept so crash recovery retries. Removal order is v6-first so v4 cleanup is unaffected.

Source

Thrown at client/firewall/iptables/manager_linux.go:345

		return firewall.SetLegacyManagement(m.router6, isLegacy)
	}
	return nil
}

// Reset firewall to the default state
func (m *Manager) Close(stateManager *statemanager.Manager) error {
	m.mutex.Lock()
	defer m.mutex.Unlock()

	var merr *multierror.Error

	if err := m.cleanupNoTrackChain(); err != nil {
		merr = multierror.Append(merr, fmt.Errorf("cleanup notrack chain: %w", err))
	}

	if m.hasIPv6() {
		if err := m.aclMgr6.Reset(); err != nil {
			merr = multierror.Append(merr, fmt.Errorf("reset v6 acl manager: %w", err))
		}
		if err := m.router6.Reset(); err != nil {
			merr = multierror.Append(merr, fmt.Errorf("reset v6 router: %w", err))
		}
	}

	if err := m.aclMgr.Reset(); err != nil {
		merr = multierror.Append(merr, fmt.Errorf("reset acl manager: %w", err))
	}
	if err := m.router.Reset(); err != nil {
		merr = multierror.Append(merr, fmt.Errorf("reset router: %w", err))
	}

	// Appending to merr intentionally blocks DeleteState below so ShutdownState
	// stays persisted and the crash-recovery path retries firewalld cleanup.
	if err := firewalld.UntrustInterface(m.wgIface.Name()); err != nil {
		merr = multierror.Append(merr, err)
	}

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Rerun Close or restart-then-stop the agent; ShutdownState.Cleanup on next start finishes the job idempotently
  2. Verify no v6 leftovers: ip6tables -S | grep NETBIRD and ipset list | grep -i netbird
  3. Manually flush/remove leftover NETBIRD v6 chains if the host must be cleaned immediately
Defensive patterns

Strategy: retry

Try / catch

closeErr := mgr.Close(stateManager)
if closeErr != nil {
    var merr *multierror.Error
    if errors.As(closeErr, &merr) {
        for _, e := range merr.Errors {
            if strings.Contains(e.Error(), "reset v6 acl manager") {
                log.Debugf("v6 ACL teardown partial (retried on next start): %v", e)
            }
        }
    }
}

Prevention

When it happens

Trigger: Close on a manager with hasIPv6() true where an ip6tables or ipset delete fails: chains already flushed by an external tool, ipset in use, or the process lost privileges.

Common situations: Double cleanup (previous crash-recovery already removed chains); firewalld/ip6tables-restore rewrites during shutdown; unprivileged stop.

Related errors


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