Summary
After updating Docker to v29 using synology-docker, the DOCKER-FORWARD chain exists but has 0 references from the built-in FORWARD chain. On Synology NAS boxes where synoiptables sets FORWARD -P DROP, this completely blocks container outbound traffic. On boxes where it leaves FORWARD -P ACCEPT, everything appears to work, but the chain is still orphaned.
Environment
- Synology DSM: 7.3.2
- Kernel: Linux 4.4.302+
- Docker version: 29.4.1 (build 6c91b92, installed via synology-docker)
- Reproduced on: Two independent Synology NAS boxes (different hardware, different network, same DSM + Docker version)
Observed iptables state after update
Chain FORWARD (policy DROP)
(empty — no rules)
Chain DOCKER-FORWARD (0 references)
DOCKER-CT all -- 0.0.0.0/0 0.0.0.0/0
DOCKER-INTERNAL all -- 0.0.0.0/0 0.0.0.0/0
DOCKER-BRIDGE all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
DOCKER-FORWARD is fully populated but unreachable — no jump rule exists in FORWARD to reach it.
Root cause
Docker v25+ changed its iptables architecture. Previously, Docker inserted rules directly into the built-in FORWARD chain on every container start (self-healing if wiped). In v25+, Docker creates a dedicated DOCKER-FORWARD chain and adds the jump rule FORWARD -j DOCKER-FORWARD once at daemon startup only. If Synology's synoiptables runs after the daemon starts and reinitialises the FORWARD chain without preserving Docker's jump rule, the rule is permanently gone until the daemon restarts.
Impact
- Boxes with
FORWARD -P DROP: all container outbound/inter-container traffic blocked immediately after update
- Boxes with
FORWARD -P ACCEPT: silently orphaned chain — traffic works via the default ACCEPT policy, but Docker's intended iptables filtering (DOCKER-CT, DOCKER-INTERNAL, etc.) is bypassed entirely
Workaround
Idempotent cron entry added to /etc/crontab:
* * * * * root /path/to/fix-iptables-forward.sh
Where fix-iptables-forward.sh contains:
#!/bin/sh
/sbin/iptables -C FORWARD -j DOCKER-FORWARD 2>/dev/null || /sbin/iptables -I FORWARD 1 -j DOCKER-FORWARD
This re-adds the jump rule within 60 seconds if it is ever wiped.
Suggestion
It may be worth adding this check to fix_ipforward.sh or switch_forward.sh, or as a new post-install step — particularly since this appears to be a systematic issue with Docker v29 on any Synology box where synoiptables manages the FORWARD chain.
Summary
After updating Docker to v29 using synology-docker, the
DOCKER-FORWARDchain exists but has 0 references from the built-inFORWARDchain. On Synology NAS boxes wheresynoiptablessetsFORWARD -P DROP, this completely blocks container outbound traffic. On boxes where it leavesFORWARD -P ACCEPT, everything appears to work, but the chain is still orphaned.Environment
Observed iptables state after update
DOCKER-FORWARDis fully populated but unreachable — no jump rule exists inFORWARDto reach it.Root cause
Docker v25+ changed its iptables architecture. Previously, Docker inserted rules directly into the built-in
FORWARDchain on every container start (self-healing if wiped). In v25+, Docker creates a dedicatedDOCKER-FORWARDchain and adds the jump ruleFORWARD -j DOCKER-FORWARDonce at daemon startup only. If Synology'ssynoiptablesruns after the daemon starts and reinitialises theFORWARDchain without preserving Docker's jump rule, the rule is permanently gone until the daemon restarts.Impact
FORWARD -P DROP: all container outbound/inter-container traffic blocked immediately after updateFORWARD -P ACCEPT: silently orphaned chain — traffic works via the default ACCEPT policy, but Docker's intended iptables filtering (DOCKER-CT, DOCKER-INTERNAL, etc.) is bypassed entirelyWorkaround
Idempotent cron entry added to
/etc/crontab:Where
fix-iptables-forward.shcontains:This re-adds the jump rule within 60 seconds if it is ever wiped.
Suggestion
It may be worth adding this check to
fix_ipforward.shorswitch_forward.sh, or as a new post-install step — particularly since this appears to be a systematic issue with Docker v29 on any Synology box wheresynoiptablesmanages theFORWARDchain.