The 'iptables failed' error occurs when Docker cannot configure network rules needed for container connectivity. This typically happens when iptables rules are flushed while Docker is running, the DOCKER chain is missing, or there are iptables version compatibility issues.
The "driver failed programming external connectivity: iptables failed" error indicates that Docker's network driver could not create or modify the iptables rules required for container networking. Docker relies heavily on iptables (Linux's firewall and NAT system) to handle port mapping, container isolation, and network address translation. When you run a container with port mappings (e.g., `docker run -p 8080:80`), Docker needs to: 1. Create NAT rules in iptables to forward traffic from the host port to the container 2. Set up the DOCKER chain in iptables for container-specific rules 3. Configure masquerading for outbound container traffic This error typically occurs when: - The DOCKER chain was deleted or never created - iptables rules were flushed by a firewall management tool while Docker was running - There's a version mismatch between iptables and Docker (especially with nftables on newer systems) - The iptables kernel modules are not loaded The full error message often includes additional details like "iptables: No chain/target/match by that name" or "iptables: Chain 'DNAT' does not exist" which help identify the specific cause.
The most common and effective fix is simply restarting Docker, which recreates all necessary iptables rules:
# Restart Docker service
sudo systemctl restart docker
# Verify Docker is running
sudo systemctl status dockerFor older systems without systemd:
sudo service docker restartAfter restarting, try running your container again. Docker will automatically recreate the DOCKER chain and all required NAT rules.
Verify whether the DOCKER chain is present in iptables:
# Check for DOCKER chain in NAT table
sudo iptables -L -n -t nat | grep -i docker
# List all chains to see if DOCKER exists
sudo iptables -S | grep DOCKERIf the DOCKER chain is missing, Docker didn't properly initialize iptables. This is often fixed by restarting Docker (Step 1), but if it persists, you may need to manually create the chain:
# Create DOCKER chain (if missing)
sudo iptables -N DOCKER
sudo iptables -t nat -N DOCKERNote: Manually creating chains is rarely necessary - restarting Docker should handle this automatically.
If you use firewalld or iptables service, make sure it starts before Docker:
# Check if firewalld is active
sudo systemctl status firewalld
# If using firewalld, restart it then Docker
sudo systemctl restart firewalld
sudo systemctl restart dockerOn RHEL/CentOS/Fedora with firewalld, you can also reload firewall rules:
# Reload firewalld without losing Docker rules (preferred)
sudo firewall-cmd --reload
sudo systemctl restart dockerFor systems using the iptables service:
sudo systemctl start iptables
sudo systemctl restart dockerUbuntu 22.04, Debian 11+, and other modern distributions use nftables by default, which can cause compatibility issues with Docker.
Check which iptables variant is active:
# Check iptables version and variant
iptables --version
# If it shows (nf_tables), you're using nftables backendSwitch to legacy iptables:
# On Debian/Ubuntu
sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
# Restart Docker
sudo systemctl restart dockerOn systems using update-alternatives:
# View available alternatives
sudo update-alternatives --config iptables
# Select the legacy option (usually option 1)Ensure the necessary kernel modules for iptables are loaded:
# Load required modules
sudo modprobe ip_tables
sudo modprobe iptable_nat
sudo modprobe iptable_filter
sudo modprobe iptable_raw
# For IPv6 support
sudo modprobe ip6_tables
sudo modprobe ip6table_natTo make these persistent across reboots, add them to modules-load.d:
# Create module configuration file
sudo bash -c 'cat > /etc/modules-load.d/docker-iptables.conf << EOF
ip_tables
iptable_nat
iptable_filter
iptable_raw
EOF'Then restart Docker:
sudo systemctl restart dockerCheck if Docker is configured to manage iptables:
# Check daemon configuration
cat /etc/docker/daemon.jsonEnsure "iptables": false is NOT set. If it is, either remove the line or set it to true:
{
"iptables": true
}You can also check Docker's startup options:
# Check Docker service configuration
sudo systemctl show docker | grep -i "ExecStart"
# Or check process
ps aux | grep dockerdLook for --iptables=false flag. If present, remove it from the service configuration.
If other steps don't work, reset Docker's network state completely:
# Stop Docker
sudo systemctl stop docker
# Remove Docker network configuration
sudo rm -rf /var/lib/docker/network
# Remove Docker bridge interface
sudo ip link delete docker0
# Start Docker
sudo systemctl start dockerDocker will recreate the network configuration and iptables rules on startup.
Warning: This may cause running containers to lose network connectivity. Ensure containers are stopped first.
If you need immediate access and can't resolve the iptables issue right away, use host networking mode:
# Run container with host networking (no port mapping needed)
docker run --network host nginx
# For docker-compose, add network_mode:
# services:
# web:
# image: nginx
# network_mode: "host"Important: Host networking bypasses Docker's network isolation. The container shares the host's network namespace directly, so:
- No port mapping is needed or possible
- Container services are directly accessible on host ports
- This reduces security isolation
- Only use as a temporary workaround
### Understanding Docker's iptables Usage
Docker uses iptables extensively for container networking:
NAT Table Rules:
- DOCKER chain: Handles port mappings and DNAT rules
- POSTROUTING chain: Masquerading for outbound container traffic
- PREROUTING chain: Redirects incoming traffic to containers
Filter Table Rules:
- DOCKER chain: Controls traffic to containers
- DOCKER-ISOLATION-STAGE-1/2 chains: Isolates container networks
- FORWARD chain: Allows forwarding between host and containers
You can view these rules with:
sudo iptables -L -n -v
sudo iptables -t nat -L -n -v### Preserving Docker Rules After Firewall Changes
If you need to manage iptables manually while keeping Docker working:
# Save current iptables rules after Docker is running
sudo iptables-save > /tmp/docker-iptables-rules
# After making firewall changes, restore Docker rules
sudo iptables-restore < /tmp/docker-iptables-rulesOr be selective about which rules you flush:
# Flush only the INPUT chain (leaves DOCKER chains intact)
sudo iptables -F INPUT
# DON'T use these with Docker running:
# sudo iptables -F # Flushes all chains
# sudo iptables -X # Deletes all user-defined chains### WSL2 and Docker Desktop Issues
On Windows Subsystem for Linux 2 (WSL2), iptables issues can occur due to:
- Missing kernel support for iptables
- Docker Desktop managing networking externally
For WSL2 with systemd:
# Ensure iptables works in WSL2
sudo update-alternatives --set iptables /usr/sbin/iptables-legacy### Rootless Docker Considerations
When running Docker in rootless mode, iptables rules are managed differently. The error may indicate that the rootless daemon cannot modify iptables (requires root). Solutions:
1. Use slirp4netns instead of vpnkit for networking
2. Grant NET_ADMIN capability if using user namespaces
3. Run specific containers with --network host as a workaround
### Debugging iptables Issues
Enable Docker daemon debug logging for more details:
# Edit daemon.json
sudo nano /etc/docker/daemon.json{
"debug": true
}Then restart Docker and check logs:
sudo systemctl restart docker
sudo journalctl -u docker -fLook for iptables-related errors in the output.
unable to configure the Docker daemon with file /etc/docker/daemon.json
How to fix 'unable to configure the Docker daemon with file daemon.json' in Docker
docker: Error response from daemon: OCI runtime create failed: container_linux.go: starting container process caused: exec: "/docker-entrypoint.sh": stat /docker-entrypoint.sh: no such file or directory
How to fix 'exec: entrypoint.sh: no such file or directory' in Docker
image operating system "linux" cannot be used on this platform
How to fix 'image operating system linux cannot be used on this platform' in Docker
dockerfile parse error line 5: unknown instruction: RRUN
How to fix 'unknown instruction' Dockerfile parse error in Docker
manifest unknown: manifest unknown
How to fix 'manifest unknown' in Docker