netbirdio/netbird · warning

cleanup notrack chain: %w

Error message

cleanup notrack chain: %w

What it means

First step of Manager.Close: cleanupNoTrackChain removes the NETBIRD-RAW chain and its OUTPUT/PREROUTING jump rules from the raw table (installed by SetupEBPFProxyNoTrack for the eBPF proxy). It fails when the raw-table iptables operations error while rawSupported is true. Like every Close error it is accumulated and intentionally blocks DeleteState, so the ShutdownState file stays persisted and the next startup's Cleanup() retries the removal.

Source

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

func (m *Manager) SetLegacyManagement(isLegacy bool) error {
	if err := firewall.SetLegacyManagement(m.router, isLegacy); err != nil {
		return err
	}
	if m.hasIPv6() {
		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))
	}

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Restart and stop the agent again: the persisted ShutdownState makes the next startup re-run Cleanup idempotently
  2. Check for leftovers as root: iptables -t raw -S | grep NETBIRD-RAW and delete the chain plus jump rules manually if stuck
  3. Capture the wrapped iptables error from the daemon log if it repeats
Defensive patterns

Strategy: retry

Try / catch

if err := mgr.Close(stateManager); err != nil {
    log.Warnf("firewall close incomplete, next start will retry via persisted state: %v", err)
    // no need to fail shutdown; ShutdownState.Cleanup is idempotent
}

Prevention

When it happens

Trigger: Manager.Close running when iptables raw-table calls fail: rule already deleted by an external flush (DeleteIfExists on vanished chains can still error at the ChainExists/ClearAndDeleteChain stage), permissions lost, or netns teardown races.

Common situations: Container runtime rewriting the raw table concurrently; agent stop during host network reconfiguration; a crash-recovery cleanup on next start encountering partially removed chains.

Related errors


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