Why is lxd chosing xtables over nftables?

I’m running lxd 4.0.2 from a snap on Debian 10 (Debian 4.19.132-1 kernel)

From reading Weekly status no 136, I think it should be using nftables (case “4” below):

It uses the following logic to pick a driver:

1 Nftables available and has a non-empty ruleset. Use nftables.
2 Nftables isn’t available. Use xtables.
3 Both nftables and xtables are available, but xtables has a non-empty ruleset. Use xtables.
4 Both nftables and xtables are available, but neither are in use. Use nftables.

From dumping the rules in use after bootup and after lxd has started, I can see:

nftables: Empty ruleset
xtables: lxd generated rules (only)

How would I go about debugging further to see why it is choosing xtables instead of nftables?

If you start LXD in debug mode:

sudo snap set lxd daemon.debug=true
sudo systemctl reload snap.lxd.daemon

Then check your /var/snap/lxd/common/lxd/logs/lxd.log file for startup messages about firewall, it should give a reason why nftables isn’t used.

The most likely reasons are that your iptables already has rules in it or that the nft command isn’t available or isn’t the right version.

The logic for selecting a firewall driver is here: https://github.com/lxc/lxd/blob/master/lxd/firewall/firewall_load.go

Thanks, that did the trick:

lxd.daemon[...] msg="Firewall detected \"nftables\" incompatibility: Kernel version does not meet minimum requirement of 5"

… it chooses nftables when using the 5.6 debian-backports kernel instead.

Right, we found that kernels pre-5.0 have some broken behavior around masquerading using nft if I recall correctly.