You can’t run iptables-legacy and nftables together on the same system. One of them has to go.

The core of the problem is that both iptables-legacy and nftables try to manage the same underlying Netfilter hooks in the Linux kernel. iptables-legacy uses the older iptables Netfilter API, while nftables uses a newer, more efficient API. When you try to load rules or run commands from both systems, they directly conflict. One will overwrite or ignore the rules of the other, leading to unpredictable and broken network behavior. You’ll see packets being dropped that shouldn’t be, or allowed when they should be blocked, because the kernel only has one set of active rules at any given time.

Here’s how to choose and stick with one:

Option 1: Migrate to nftables (Recommended)

nftables is the modern replacement for iptables, ip6tables, arptables, and ebtables. It’s more efficient, has a cleaner syntax, and offers more advanced features. Most modern Linux distributions are moving towards nftables as the default.

  1. Check if nftables is already in use:

    sudo nft list ruleset
    

    If this command shows rules, you’re likely already using nftables. If it shows nothing or an error about no ruleset, you might be on iptables-legacy or have no firewall configured.

  2. If you have iptables-legacy rules you want to keep: Convert them to nftables syntax. The iptables-translate tool is your best friend here.

    sudo iptables-save > /tmp/iptables.rules
    sudo iptables-translate -f /tmp/iptables.rules > /tmp/nftables.rules
    

    Carefully review /tmp/nftables.rules. The translation isn’t always perfect, especially for complex rules or custom iptables modules. You’ll likely need to make manual adjustments.

  3. Apply the nftables rules: Once you’re satisfied with the translated rules:

    sudo nft -f /tmp/nftables.rules
    

    This loads your converted ruleset into the kernel.

  4. Disable and uninstall iptables-legacy: To prevent conflicts, ensure iptables-legacy services are stopped and the package is removed. The exact service name might vary by distribution (e.g., iptables, netfilter-persistent).

    # For systems using systemd
    sudo systemctl stop iptables
    sudo systemctl disable iptables
    sudo apt-get remove iptables-legacy iptables-legacy-persistent # Debian/Ubuntu example
    # or
    sudo yum remove iptables-services # RHEL/CentOS example
    
  5. Make nftables persistent: Most distributions have a way to load nftables rules on boot. For example, on Debian/Ubuntu:

    sudo apt-get install nftables
    sudo systemctl enable nftables
    # Then, copy your active ruleset to the default location
    sudo cp /etc/nftables.conf /etc/nftables.conf.backup # Backup existing config if any
    sudo nft list ruleset > /etc/nftables.conf
    

    On RHEL/CentOS 8+, nftables is often the default. You might need to configure /etc/sysconfig/nftables.conf or ensure the nftables service is enabled.

Option 2: Stick with iptables-legacy

If you have a strong reason to stay with iptables-legacy (e.g., specific legacy scripts, hardware compatibility, or you’re just more comfortable with it), you need to ensure nftables is not installed or not active.

  1. Check if nftables is installed and active:

    sudo systemctl status nftables
    # or
    dpkg -s nftables # Debian/Ubuntu
    rpm -q nftables # RHEL/CentOS
    
  2. Disable and uninstall nftables: If nftables is installed and running, stop its service and remove the package.

    sudo systemctl stop nftables
    sudo systemctl disable nftables
    sudo apt-get remove nftables # Debian/Ubuntu example
    # or
    sudo yum remove nftables # RHEL/CentOS example
    
  3. Ensure iptables-legacy is installed and configured: Make sure the iptables-legacy package and its persistence service are installed.

    sudo apt-get install iptables-legacy iptables-legacy-persistent # Debian/Ubuntu example
    # or
    sudo yum install iptables-services # RHEL/CentOS example
    
  4. Load your iptables-legacy rules: If you have rules saved, load them.

    sudo iptables-restore < /etc/iptables/rules.v4 # Example for Debian/Ubuntu
    # or
    sudo service iptables restart # Example for RHEL/CentOS
    
  5. Verify iptables-legacy is managing rules:

    sudo iptables -L -n -v
    

    This command should show your rules. If it shows an error or no rules, the iptables-legacy service might not be running correctly.

Why this matters:

The kernel’s Netfilter subsystem is the heart of Linux packet filtering. It exposes hooks at various points in the network stack where firewall modules can inspect and manipulate packets. iptables-legacy and nftables are two different user-space tools that interact with these hooks. They use different mechanisms to load and manage the rules that the kernel then enforces. When both try to do this simultaneously, they’re essentially fighting over who gets to tell the kernel what to do, leading to a complete breakdown in firewall logic. It’s like two people trying to write on the same whiteboard at the same time with different markers – you just get a mess.

The next error you’ll hit if you try to run both will likely be related to Netfilter module conflicts or unexpected packet drops, manifesting as services becoming unreachable or the system losing network connectivity entirely.

Want structured learning?

Take the full Iptables course →