netbirdio/netbird · error

reset nftables manager: %w

Error message

reset nftables manager: %w

What it means

Returned by ShutdownState.Cleanup (client/firewall/nftables/state_linux.go:43) when nft.Close(nil) fails. Close flushes the teardown of the netbird-managed nftables objects (chains/table created during this recovery Create), so failure means the kernel refused the cleanup batch: EPERM, the table already deleted by another client (ENOENT), or a netlink I/O error. The leftover state this error implies is leftover nftables rules, not lost connectivity.

Source

Thrown at client/firewall/nftables/state_linux.go:43

	InterfaceState *InterfaceState `json:"interface_state,omitempty"`
}

func (s *ShutdownState) Name() string {
	return "nftables_state"
}

func (s *ShutdownState) Cleanup() error {
	mtu := s.InterfaceState.MTU
	if mtu == 0 {
		mtu = iface.DefaultMTU
	}
	nft, err := Create(s.InterfaceState, mtu)
	if err != nil {
		return fmt.Errorf("create nftables manager: %w", err)
	}

	if err := nft.Close(nil); err != nil {
		return fmt.Errorf("reset nftables manager: %w", err)
	}

	return nil
}

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Re-run the recovery once after verifying privileges; a recreated manager's Close will flush whatever objects still exist
  2. Check 'nft list ruleset' for residual netbird chains/table and delete them manually if cleanup keeps failing
  3. Ensure only one agent instance performs state recovery at a time (lock file / single daemon instance)
  4. Treat ENOENT-class failures as success: the state to clean is already gone

Example fix

// before
if err := nft.Close(nil); err != nil {
    return fmt.Errorf("reset nftables manager: %w", err)
}
// after
if err := nft.Close(nil); err != nil {
    if isNotExistErr(err) {
        return nil
    }
    return fmt.Errorf("reset nftables manager: %w", err)
}
Defensive patterns

Strategy: fallback

Try / catch

if err := shutdownState.Cleanup(); err != nil {
    switch {
    case isNotExistErr(rootCause(err)):
        return nil // objects already cleaned
    default:
        log.Warnf("nftables leftovers may remain until reboot: %v", err)
        return nil
    }
}

Prevention

When it happens

Trigger: Another nftables client (operator, firewalld, a second agent instance) removed the netbird table between Create and Close; capabilities dropped mid-run; netlink socket closed during namespace teardown.

Common situations: Crash-recovery racing with an operator manually cleaning nftables; two agent processes recovering the same state; container runtime tearing down the net namespace while cleanup runs.

Related errors


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