Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for DevOps Security & Hardening By James Joyner IV · · 9 min read

Security Error Guide: 'firewalld COMMAND_FAILED' iptables Rule Apply Failure

Fix firewalld 'COMMAND_FAILED' / 'INVALID_RULE' errors: diagnose nftables vs iptables backend conflicts, bad direct rules, missing kernel modules, and reload firewalld safely.

  • #security-hardening
  • #troubleshooting
  • #errors
  • #firewalld

Exact Error Message

When firewalld cannot push a rule into the kernel, it raises COMMAND_FAILED and leaves the change unapplied:

Error: COMMAND_FAILED: '/usr/sbin/iptables-restore -w -n' failed:
iptables-restore v1.8.7 (legacy): Couldn't load match `conntrack':No such file or directory

Related variants engineers see during hardening:

Error: COMMAND_FAILED: INVALID_RULE: unknown element 'reject-with' in rule
Error: COMMAND_FAILED: '/usr/sbin/iptables-restore -w -n' failed: Another app is currently holding the xtables lock

What the Error Means

firewalld is a front end that translates zones, services, and direct rules into kernel firewall rules through a backend (nftables by default on modern systems, or the iptables legacy/nft shims). COMMAND_FAILED means the backend command firewalld invoked returned an error, so the rule was rejected. The kernel firewall is left in its previous state; your intended hardening rule did not take effect.

This is a configuration or environment mismatch, not an attack. Common triggers include a missing kernel module the rule depends on, a malformed --direct rule, a backend mismatch between firewalld’s config and what is installed, or another process holding the xtables lock. The fix is to read the underlying backend error firewalld is wrapping, correct the rule or environment, and reload cleanly.

Common Causes

  • Missing kernel module. A match like conntrack or recent needs a module that is not loaded or not present, so iptables-restore fails to load the match.
  • Backend mismatch. firewalld is configured for iptables but the host only has the nft backend (or vice versa), so the invoked binary behaves unexpectedly.
  • Malformed direct rule. A hand-written --direct --add-rule has a syntax error (INVALID_RULE) that the backend rejects.
  • xtables lock contention. Another tool (a script, Docker, fail2ban) holds the xtables lock while firewalld tries to apply rules.
  • nftables/iptables coexistence. Mixed iptables-legacy and iptables-nft rules collide, and a restore fails partway.
  • Stale runtime vs permanent config. A --permanent change references a service or module that does not exist at reload time.

How to Reproduce the Error

On a test host, add a direct rule that references a match whose module is unavailable, then reload:

sudo firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 \
  -m conntrack --ctstate INVALID -j DROP
sudo modprobe -r nf_conntrack 2>/dev/null
sudo firewall-cmd --reload
Error: COMMAND_FAILED: '/usr/sbin/iptables-restore -w -n' failed:
iptables-restore: Couldn't load match `conntrack':No such file or directory

Diagnostic Commands

These read-only commands surface the real backend error and the current firewall state.

# Read firewalld's own log for the wrapped backend error
sudo journalctl -u firewalld --since '15 min ago' | grep -iE 'COMMAND_FAILED|INVALID|error'

# What backend is firewalld using?
sudo firewall-cmd --state
grep -i FirewallBackend /etc/firewalld/firewalld.conf

# List the active zones, services, and direct rules (read-only)
sudo firewall-cmd --list-all-zones
sudo firewall-cmd --direct --get-all-rules

# Inspect the actual kernel ruleset (nft and iptables views)
sudo nft list ruleset 2>/dev/null | head -40
sudo iptables -S 2>/dev/null | head -40

# Which firewall-related kernel modules are loaded?
lsmod | grep -E 'conntrack|nf_tables|ip_tables|xt_'

# Is something else holding the xtables lock or managing the firewall?
ss -tlnp 2>/dev/null | head
sudo journalctl --since '15 min ago' | grep -iE 'xtables lock|fail2ban|docker.*iptables'

The firewalld journal line is the key artifact: it contains the exact backend command and the error string it returned, which names the missing match, bad rule, or lock.

Step-by-Step Resolution

  1. Read the wrapped error. journalctl -u firewalld shows the actual iptables-restore/nft failure behind COMMAND_FAILED. The string after “failed:” names the precise problem (missing match, invalid element, held lock).

  2. For a missing module, confirm and load it (or remove the rule that needs it):

    sudo modprobe nf_conntrack

    Ensure the module is set to load at boot if the rule must persist.

  3. For a backend mismatch, align FirewallBackend in /etc/firewalld/firewalld.conf with what the host supports (modern systems prefer nftables), then reload. Do not mix legacy and nft rule tools on the same host.

  4. For an INVALID_RULE, correct the direct rule syntax. Remove the bad rule first so reload succeeds, then re-add a valid version:

    sudo firewall-cmd --permanent --direct --remove-rule ipv4 filter INPUT 0 <bad-rule-args>
  5. For xtables lock contention, identify and serialize the other writer (fail2ban, Docker, a deploy script). firewalld uses -w to wait, but a long-held lock still fails; retry after the other tool finishes.

  6. Reload and verify the rule is actually in the kernel, not just in config:

    sudo firewall-cmd --reload
    sudo nft list ruleset | grep -i drop   # or: sudo iptables -S

Prevention and Best Practices

  • Prefer firewalld’s native rich rules and services over hand-written --direct rules; they are validated and portable across backends.
  • Standardize on one backend (nftables on modern hosts) and avoid mixing iptables-legacy and iptables-nft tooling.
  • Ensure any kernel modules your rules depend on (e.g. nf_conntrack) are loaded at boot.
  • Coordinate firewall writers — fail2ban, Docker, deploy scripts — so they do not collide with firewalld over the xtables lock.
  • Test rule changes against the runtime config first, then commit with --permanent, and always reload before assuming a rule is live.
  • INVALID_RULE — a malformed direct or rich rule firewalld refused to accept.
  • ZONE_CONFLICT / ALREADY_ENABLED — zone/service binding issues, distinct from backend failures.
  • Another app is currently holding the xtables lock — concurrency with another firewall tool.
  • iptables: No chain/target/match by that name — a missing module or typo, related and covered in the security hardening guides.

Frequently Asked Questions

My rule shows in firewall-cmd --list-all but traffic is not filtered. COMMAND_FAILED can leave the permanent config containing a rule that never applied to the kernel. Check nft list ruleset/iptables -S for the actual live rules.

Why does it say Couldn't load match? The rule uses a match (conntrack, recent, etc.) whose kernel module is missing or not loaded. Load the module or remove the rule.

Should I switch firewalld to the iptables backend to fix this? Usually no — align to nftables on modern hosts. Switching backends to dodge an error often trades one mismatch for another.

What is holding the xtables lock? Commonly fail2ban or Docker manipulating iptables concurrently. Find the writer in the journal and serialize firewall changes.

Is --direct safe to keep using? It works but bypasses firewalld’s validation and portability. Prefer rich rules; reserve --direct for cases firewalld cannot express natively.

Free download · 368-page PDF

Download the Free 500-Prompt DevOps AI Toolkit

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.