Skip to content

Docker v29: DOCKER-FORWARD chain orphaned after update — container outbound traffic blocked when FORWARD policy is DROP #66

@ccarpinteri

Description

@ccarpinteri

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.

Metadata

Metadata

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions