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
- Restart and stop the agent again: the persisted ShutdownState makes the next startup re-run Cleanup idempotently
- Check for leftovers as root: iptables -t raw -S | grep NETBIRD-RAW and delete the chain plus jump rules manually if stuck
- 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
- Trust the persisted ShutdownState: an incomplete Close is retried on next start
- Keep the agent's state directory writable so the state file survives for recovery
- After force-kills, start/stop the agent once to let recovery finish raw-table cleanup
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
- remove v4 NAT rule: %w
- remove v6 NAT rule: %w
- reset v6 acl manager: %w
- reset v6 router: %w
- reset acl manager: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/3d76d8bff77a9c0e.
Report an issue: GitHub.