/errors/iptables/bad-rule-does-a-matching-rule-exist-in-that-chain
iptables: Bad rule (does a matching rule exist in that chain?).
- tool
- iptables / nftables
- exit code
- 1
- versions
- iptables 1.4+, iptables 1.8 (legacy and nf_tables)
- os
- linux
iptables: Bad rule (does a matching rule exist in that chain?). means iptables could not find the rule you asked it to delete (-D) or check (-C): no rule in that chain of that table matches your specification exactly. The rule must match option for option, including matches such as -m tcp and the table (-t nat). List the chain with iptables -S CHAIN, copy the rule from that output and change -A to -D, or delete it by its line number.
Find the exact rule
iptables -S INPUT # rules as iptables commands
iptables -t nat -S POSTROUTING # rules in another table
iptables -L INPUT -n --line-numbers # rules with their positionsRun them as root. iptables -S prints each rule in the canonical form iptables uses when it compares rules, for example -A INPUT -p tcp -m tcp --dport 8080 -j ACCEPT. Deleting with that exact text (with -D instead of -A) works:
iptables -D INPUT -p tcp -m tcp --dport 8080 -j ACCEPT
iptables -D INPUT 5 # or by position from --line-numbersLine numbers change after each deletion, so list again before deleting the next rule by number.
In scripts
-C returns exit status 0 when the rule exists and 1 with this message when it does not, so it is the idiomatic way to make scripts idempotent:
iptables -C INPUT -p tcp --dport 8080 -j ACCEPT 2>/dev/null \
&& iptables -D INPUT -p tcp --dport 8080 -j ACCEPT
iptables -C INPUT -p tcp --dport 8080 -j ACCEPT 2>/dev/null \
|| iptables -A INPUT -p tcp --dport 8080 -j ACCEPTWhere the text comes from
Both backends map the "no such entry" error of -D and -C to the same text: libiptc for the legacy backend (-C runs the same lookup as -D without deleting), and nft_strerror() in iptables/nft.c for the nf_tables backend (iptables v1.8.x (nf_tables)). The program prints it as iptables: MESSAGE. and exits with status 1.
Rules created with nft directly are not iptables rules, and firewall managers keep theirs in their own chains (ufw uses chains such as ufw-user-input). If the rule is not in the chain you are editing, find it with iptables -S (all chains) or nft list ruleset, and remove it with the tool that manages it.