iptables: line 1: Syntax error at position — rule failed
You mistyped a rule. iptables doesn't guess — it breaks. Here's exactly how to find and fix the typo.
Quick answer
Run iptables -S | grep -E '^(#[^ ]|[^#])' to dump current rules, then check the failing line against iptables-save syntax. The error position tells you which argument is bad — start counting from 1 at the first word after -A.
Why this happens
You typed a rule and iptables kicked it back. This isn't a bug — it's a guardrail. iptables is strict because one wrong rule can punch a hole in your firewall or lock you out entirely. The error usually shows up when you're running a command like iptables -A INPUT -p tcp --dport 80 -j ACCEPT and you flip --dport to --dportt or use --sport where you meant --dport. It also happens when you use a chain name that doesn't exist — like INPTU instead of INPUT — or a target that's not loaded, like REJECT when the reject module isn't available.
I've seen this exact error on Ubuntu 22.04 and RHEL 9 when someone's copying a rule from a forum post and pastes a curly quote (curly quotes break iptables). Another common trigger: trying to use --state without loading the conntrack module first.
Fix steps
- Write down the exact error line. iptables shows the rule it choked on. For example:
iptables v1.8.7: Syntax error at position 24. Note that position number. - Count characters from the start of the rule (including spaces) to find the bad token. In the rule
-A INPUT -p tcp --dport 80 -j ACCEPT, position 24 lands at--dportif the typo is there. Use this command to count:echo "-A INPUT -p tcp --dport 80 -j ACCEPT" | grep -oP '.{0,23}\K.'— that shows the 24th character. - Look at what's wrong at that position. Common issues at that spot: a misspelled flag like
--dportt(extra t), a missing dash (should be--dportbut you wrote-dport), or a protocol name that's wrong (e.g.,tcptyped astcpip). - Check the chain name first. Half the time the error is at position 3–6 because you typed
INPUTasINPTU. Runiptables -Lto list existing chains. Your chain name must match exactly. - Verify the target. Targets like
ACCEPT,DROP,REJECT,LOGmust be spelled right.ACCEPTis notACCEPTED.REJECTrequires thext_rejectmodule — on minimal installs you might needmodprobe xt_rejectfirst. - Check protocol and module loading. If you use
--state, iptables needsxt_conntrack. If you use--dport, you must specify a protocol (-p tcpor-p udp). iptables won't guess. - Test the fixed rule with
--dry-run. Some iptables versions supportiptables -A ... --dry-run. If yours doesn't, build the rule in a text editor and paste it. No quotes around flags unless the value has spaces. - Apply the corrected rule. Run the full command again. You should see no output — that means success. Verify with
iptables -L -n -vand check the packet and byte counters.
Alternative fixes
- Use iptables-save to reload the whole ruleset instead of adding rules one by one. Dump current rules with
iptables-save > /tmp/rules.v4, edit the file, then load withiptables-restore < /tmp/rules.v4. This catches syntax errors before they hit the kernel. - Switch to nftables if you keep hitting syntax walls. nftables uses a saner syntax:
nft add rule inet filter input tcp dport 80 accept. It's the future — RHEL 9 and Ubuntu 22.04 ship it by default. - Use a firewall frontend like
ufw(Ubuntu) orfirewalld(RHEL). They generate iptables rules from simple commands. For example,ufw allow 80/tcpworks every time.
Prevention tip
Always test new rules in a non-destructive way. Run iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT as a dry test — if it fails, your existing rules are untouched. Keep a backup: iptables-save > /root/firewall-$(date +%F).bak. And for crying out loud, never paste rules from a web browser without checking for smart quotes. Use cat -v to reveal hidden characters in your command.
Was this solution helpful?