netbirdio/netbird · warning

reset acl manager: %w

Error message

reset acl manager: %w

What it means

During Manager.Close, the v4 aclMgr.Reset() failed - removing NETBIRD-ACL-INPUT, its jump rule from INPUT, optional entries, and v4 ipsets. It runs after the v6 resets and is likewise accumulated, never aborting the remaining v4 router reset or firewalld untrust. Blocked DeleteState keeps the shutdown state persisted for retry.

Source

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

	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)
	}

	// attempt to delete state only if all other operations succeeded
	if merr == nil {
		if err := stateManager.DeleteState(&ShutdownState{}); err != nil {
			merr = multierror.Append(merr, fmt.Errorf("delete state: %w", err))
		}
	}

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Re-run Close, or restart and stop the agent so next-start Cleanup retries
  2. Confirm cleanliness with iptables -S INPUT | grep NETBIRD and ipset list
  3. Remove leftover NETBIRD-ACL-INPUT chain by hand if immediate cleanup is required
Defensive patterns

Strategy: retry

Try / catch

if err := mgr.Close(stateManager); err != nil {
    var merr *multierror.Error
    if errors.As(err, &merr) {
        for _, e := range merr.Errors {
            log.Debugf("firewall teardown partial: %v", e)
        }
    }
    // ShutdownState persists; next start re-runs Cleanup
}

Prevention

When it happens

Trigger: Close where a v4 iptables or ipset delete errors: chain INPUT's jump already removed, ipset still referenced, permissions dropped before teardown.

Common situations: Prior crash-recovery cleanup already removed v4 chains; concurrent iptables rewrite; agent stopped without root.

Related errors


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