Fixing the “Failed to Setup IP tables” Error in Docker on WSL2
TL;DR:
If you see this error when running Docker on Windows Subsystem for Linux (WSL2):
ERROR: Failed to Setup IP tables: Unable to enable SKIP DNAT rule:
(iptables failed: iptables --wait -t nat -I DOCKER -i br-xxxx -j RETURN:
iptables: No chain/target/match by that name. (exit status 1))
👉 The cause is usually that your system is using the nftables backend for iptables, but Docker expects the legacy backend.
Switching iptables to legacy mode and restarting Docker fixes it:
sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
Then restart Docker and verify:
sudo iptables -t nat -L
You should now see the DOCKER chain listed. ✅
🔍 Understanding the Problem
When Docker starts, it configures internal network bridges using iptables.
If it cannot find or manipulate its DOCKER chain, you’ll see this “Failed to Setup IP tables” error.
This problem often occurs in WSL2 environments, where the Linux kernel uses the newer nftables system by default, while Docker still relies on the legacy iptables interface.
In short:
iptables-nft(default in modern WSL2) ≠iptables-legacy(expected by Docker)- The mismatch causes Docker to fail to configure NAT and bridge rules
⚙️ Step-by-Step Fix
1️⃣ Check which iptables backend you’re using
sudo iptables --version
sudo update-alternatives --display iptables
If you see something like iptables v1.8.x (nf_tables), you’re using nftables.
2️⃣ Switch to legacy mode
sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
Confirm the change:
sudo iptables --version
Now it should say (legacy).
3️⃣ Restart Docker
If you’re using Docker Desktop for Windows:
wsl --shutdown
net stop com.docker.service
net start com.docker.service
or simply quit and reopen Docker Desktop.
If you’re running Docker Engine inside WSL:
sudo service docker restart
4️⃣ Verify the fix
sudo iptables -t nat -L
You should now see the DOCKER chain among the NAT rules:
Chain DOCKER (2 references)
target prot opt source destination
RETURN all -- anywhere anywhere
If it appears — congratulations 🎉 — your Docker networking is fixed!
🧠 Extra Troubleshooting Tips
- If the error persists, flush and rebuild the NAT table:
sudo service docker stop sudo iptables -t nat -F sudo iptables -t nat -X sudo service docker start - Check kernel modules (for completeness):
lsmod | grep iptable sudo modprobe iptable_nat - Keep Docker Desktop and WSL2 kernel up to date — many network issues are fixed in newer builds.
✅ Summary
| Step | Command | Goal |
|---|---|---|
| Check backend | sudo iptables --version |
Identify nft vs legacy |
| Switch mode | update-alternatives --set ... legacy |
Use legacy backend |
| Restart Docker | sudo service docker restart |
Reload NAT rules |
| Verify | sudo iptables -t nat -L |
Confirm DOCKER chain exists |
🚀 Conclusion
This “Failed to Setup IP tables” issue is one of the most frequent Docker-on-WSL2 networking errors.
The root cause lies in the nftables vs legacy backend mismatch — a subtle but critical difference in Linux networking subsystems.
Once you switch to the legacy backend and restart Docker, everything should work smoothly again.
By keeping your WSL2 kernel, Docker Engine, and iptables configuration aligned, you can prevent these issues and maintain a stable developer environment on Windows.
Happy containerizing! 🐋