/commands/iptables/iptables-delete-rule
iptables -D: delete a rule by number or by specification
- tool
- iptables / nftables
- versions
- iptables 1.8
- os
- linux
sudo iptables -D CHAIN NUMBER deletes the rule at that position (numbers start at 1), and sudo iptables -D CHAIN RULE-SPEC deletes the first rule that matches the specification exactly as it was added. Find the number with iptables -L CHAIN --line-numbers, or print the specification with iptables -S CHAIN and replace -A with -D.
sudo iptables -L INPUT -n --line-numbers # find the position
sudo iptables -D INPUT 3 # delete rule number 3 of INPUT
sudo iptables -S INPUT # print rules as -A ... specifications
sudo iptables -D INPUT -p tcp --dport 8080 -j ACCEPT # delete by specification
sudo iptables -t nat -D PREROUTING 1 # other tables need -tBy number or by specification
| Form | When to use it | Pitfall |
|---|---|---|
| -D INPUT 3 | Interactive cleanup right after listing the rules. | Numbers shift after every delete or insert; list again before the next delete. |
| -D INPUT -p tcp --dport 8080 -j ACCEPT | Scripts, because it does not depend on the order. | Every match and target must be the same as in the rule, or nothing matches. |
| -C INPUT ... then -D INPUT ... | Delete only if the rule exists, without an error. | -C returns non-zero when the rule is missing; check the exit code. |
| -F INPUT | Remove every rule of one chain. | The chain policy stays; with policy DROP all traffic is blocked. |
| -X CHAIN | Delete a user-defined chain. | The chain must be empty and no rule may jump to it. |
Delete by copying the -S line
The -S output is the exact form iptables stores, which makes it the safest source for a delete:
sudo iptables -S INPUT
# -P INPUT ACCEPT
# -A INPUT -s 203.0.113.7/32 -j DROP
sudo iptables -D INPUT -s 203.0.113.7/32 -j DROPThe # ... lines show the shape of the output, not a captured run. Writing the rule from memory often fails because iptables normalises it (an address becomes /32, a module such as -m tcp is added), although iptables also accepts the original short form in most cases.
Errors
iptables: Bad rule (does a matching rule exist in that chain?).: no rule matches the specification, or the number is past the end of the chain. See Bad rule.iptables: No chain/target/match by that name.: wrong chain name (chains are case sensitive:INPUT, notinput) or the rule is in another table. See No chain/target/match by that name.Permission denied (you must be root): run withsudo. See Permission denied.
Confirm and persist
List the chain again with iptables -L INPUT -n -v --line-numbers to check the rule is gone. Then save, as shown in save iptables rules permanently.
FAQ
Does iptables -D remove the rule permanently?
It removes it from the running kernel ruleset only. If your rules are loaded at boot from a saved file (netfilter-persistent, iptables-services), save again with iptables-save after deleting, or the rule comes back after a reboot.
How do I delete all rules at once?
iptables -F flushes every chain of the filter table, iptables -F INPUT only that chain. Flushing does not change chain policies: with a DROP policy on INPUT, an empty chain blocks everything, including your SSH session.
Do I need to delete IPv6 rules separately?
Yes. iptables manages only IPv4. IPv6 rules live in a separate ruleset managed with ip6tables, which takes the same -D syntax.