Bug:Title: Kernelspace WireGuard implementation causes VPN-side NAT mapping to expire during idle UDP traffic (breaks torrent DHT), userspace does not
Is this urgent?
No
Host OS
Ubuntu Server 26,04 LTS
CPU arch
x86_64
VPN service provider
Privado
What are you using to run the container
docker-compose
What is the version of Gluetun
2026-09-01T23:04:47.130Z
What's the problem
When using a custom WireGuard provider (Privado, no official port forwarding), switching gluetun's WireGuard implementation from userspace to kernelspace (the current auto default when the kernel module is available) causes inbound UDP traffic to silently stop being deliverable after a period of low outbound traffic on a given port — specifically breaking BitTorrent DHT for qBittorrent running via network_mode: service:gluetun.
With WIREGUARD_IMPLEMENTATION=userspace, DHT node counts remain stable over many hours of idle periods. With auto/kernelspace, DHT node counts gradually decay to 0 and never recover without a full container restart.
Steps to reproduce Run gluetun with VPN_SERVICE_PROVIDER=custom, VPN_TYPE=wireguard, connected to a provider with no official port forwarding (Privado in my case) Run qBittorrent (linuxserver image) with network_mode: service:gluetun Leave the client mostly idle (no active downloads) for several hours Observe DHT node count in qBittorrent's WebUI gradually drop to 0 and never recover Restart the stack — DHT briefly repopulates, then decays again over time Expected behavior
DHT node count should remain stable during idle periods, consistent with behavior observed when WIREGUARD_IMPLEMENTATION=userspace is explicitly set.
Actual behavior
Only occurs with kernelspace WireGuard (auto default, confirmed via logs: Using available kernelspace implementation). Setting WIREGUARD_IMPLEMENTATION=userspace explicitly resolves the issue completely — DHT nodes remain populated after several hours of no activity.
Environment gluetun image: qmcgaw/gluetun:latest (please note actual version tag/commit if you can get it — see note below) VPN_SERVICE_PROVIDER: custom VPN_TYPE: wireguard Provider: Privado (no official port forwarding support) Host: [add: OS / kernel version, e.g. Ubuntu 24.04, kernel 6.x] qBittorrent image: lscr.io/linuxserver/qbittorrent:latest
Additional context
This regression appeared after rebuilding the Docker host and re-pulling :latest images — the same WireGuard keys, same VPN server, and same compose configuration had worked reliably for months prior on an older gluetun version, which (as far as I can tell) was always using the userspace implementation since kernelspace detection didn't exist yet.
My working theory: kernelspace WireGuard's NAT/conntrack refresh behavior for the tunnel differs from the userspace implementation in a way that causes the VPN provider's exit-server NAT mapping for sparse/low-frequency UDP traffic (like DHT) to expire, whereas userspace's behavior keeps it alive. This isn't caught by gluetun's own healthcheck since the WireGuard tunnel to the VPN server itself never drops — only inbound reachability for certain traffic patterns is affected.
Workaround
Setting WIREGUARD_IMPLEMENTATION=userspace explicitly fixes the issue.
Share your logs (at least 10 lines)
========================================
========================================
=============== gluetun ================
========================================
=========== Made with ❤️ by ============
======= https://github.com/qdm12 =======
========================================
========================================
Running version latest built on 2026-09-01T23:04:47.130Z (commit 0fef7b2) on Linux 7.0.0-31-generic (x86_64)
Need help? ☕ Discussion? https://github.com/qdm12/gluetun/discussions/new/choose
Bug? ✨ New feature? https://github.com/qdm12/gluetun/issues/new/choose
Email? [email protected]
Help me? https://www.paypal.me/qmcgaw https://github.com/sponsors/qdm12
2026-09-07T13:05:04Z WARN You are using the old environment variable VPN_ENDPOINT_IP, please consider changing it to OPENVPN_ENDPOINT_IP
2026-09-07T13:05:04Z WARN You are using the old environment variable VPN_ENDPOINT_PORT, please consider changing it to OPENVPN_ENDPOINT_PORT
2026-09-07T13:05:04Z WARN You are using the old environment variable VPN_ENDPOINT_IP, please consider changing it to WIREGUARD_ENDPOINT_IP
2026-09-07T13:05:04Z WARN You are using the old environment variable VPN_ENDPOINT_PORT, please consider changing it to WIREGUARD_ENDPOINT_PORT
2026-09-07T13:05:04Z INFO [routing] default route found: interface eth0, gateway 172.19.0.1, assigned IP 172.19.0.2 and family v4
2026-09-07T13:05:04Z INFO [routing] local ethernet link found: eth0
2026-09-07T13:05:04Z INFO [routing] local ipnet found: 172.19.0.0/16
2026-09-07T13:05:04Z INFO [firewall] enabling...
2026-09-07T13:05:04Z INFO [firewall] enabled successfully
2026-09-07T13:05:04Z INFO [storage] writing servers data files to /gluetun/servers/ with 26611 hardcoded servers
2026-09-07T13:05:04Z INFO Alpine version: 3.23.5
2026-09-07T13:05:04Z INFO OpenVPN version: 2.6.20
2026-09-07T13:05:04Z INFO Firewall version: iptables v1.8.11
2026-09-07T13:05:04Z INFO Settings summary:
├── VPN settings:
| ├── VPN provider settings:
| | ├── Name: custom
| | └── Server selection settings:
| | ├── VPN type: wireguard
| | └── Wireguard selection settings:
| | ├── Endpoint IP address: 91.148.228.128
| | ├── Endpoint port: 51820
| | └── Server public key: =
| ├── Wireguard settings:
| | ├── Private key: qKg...l8=
| | ├── Interface addresses:
| | | └── 100.64.141.217/32
| | ├── Allowed IPs:
| | | ├── 0.0.0.0/0
| | | └── ::/0
| | ├── Persistent keepalive interval: 10s
| | ├── Network interface: tun0
| | | └── MTU: use path MTU discovery
| | └── Implementation: userspace
| └── Path MTU discovery:
| ├── ICMP addresses:
| | ├── 1.1.1.1
| | └── 8.8.8.8
| └── TCP addresses:
| ├── 1.1.1.1:443
| ├── 8.8.8.8:443
| ├── 1.1.1.1:53
| ├── 8.8.8.8:53
| ├── [2606:4700:4700::1111]:53
| ├── [2001:4860:4860::8888]:53
| ├── [2606:4700:4700::1111]:443
| └── [2001:4860:4860::8888]:443
├── DNS settings:
| ├── Upstream resolver type: dot
| ├── Upstream resolvers:
| | └── Cloudflare
| ├── Caching: yes
| ├── IPv6: no
| ├── Update period: every 24h0m0s
| └── DNS filtering settings:
| ├── Block malicious: yes
| └── Block ads: no
├── Firewall settings:
| ├── Enabled: yes
| ├── Iptables settings:
| | └── Log level: info
| ├── Input ports:
| | ├── 8080
| | └── 54321
| └── Outbound subnets:
| └── 192.168.111.0/24
├── Log settings:
| └── Log level: info
├── IPv6 settings:
| └── Check addresses:
| ├── [2001:4860:4860::8888]:53
| └── [2606:4700:4700::1111]:53
├── Metrics settings:
| └── Type: noop
├── Health settings:
| ├── Server listening address: 127.0.0.1:9999
| ├── Target addresses:
| | ├── cloudflare.com:443
| | └── github.com:443
| ├── Small health check type: ICMP echo request
| | └── ICMP target IPs:
| | ├── 1.1.1.1
| | └── 8.8.8.8
| └── Restart VPN on healthcheck failure: yes
├── SOCKS5 proxy server settings:
| └── Enabled: no
├── Shadowsocks server settings:
| └── Enabled: no
├── HTTP proxy settings:
| └── Enabled: no
├── Control server settings:
| ├── Listening address: :8000
| ├── Logging: yes
| └── Authentication file path: /gluetun/auth/config.toml
├── Storage settings:
| └── Servers directory path: /gluetun/servers/
├── OS Alpine settings:
| ├── Process UID: 1000
| └── Process GID: 1000
├── Public IP settings:
| ├── IP file path: /tmp/gluetun/ip
| ├── Public IP data base API: ipinfo
| └── Public IP data backup APIs:
| ├── ifconfigco
| ├── ip2location
| └── cloudflare
└── Version settings:
└── Enabled: yes
2026-09-07T13:05:04Z INFO [routing] default route found: interface eth0, gateway 172.19.0.1, assigned IP 172.19.0.2 and family v4
2026-09-07T13:05:04Z INFO [routing] adding route for 0.0.0.0/0
2026-09-07T13:05:04Z INFO [firewall] setting allowed subnets...
2026-09-07T13:05:04Z INFO [routing] default route found: interface eth0, gateway 172.19.0.1, assigned IP 172.19.0.2 and family v4
2026-09-07T13:05:04Z INFO [routing] adding route for 192.168.111.0/24
2026-09-07T13:05:04Z INFO [firewall] setting allowed input port 8080 through interface eth0...
2026-09-07T13:05:04Z INFO [firewall] setting allowed input port 54321 through interface eth0...
2026-09-07T13:05:04Z INFO [healthcheck] listening on 127.0.0.1:9999
2026-09-07T13:05:04Z INFO [http server] http server listening on [::]:8000
2026-09-07T13:05:04Z INFO [firewall] allowing VPN connection...
2026-09-07T13:05:04Z INFO [wireguard] Connecting to 91.148.228.128:51820
2026-09-07T13:05:04Z INFO [vpn] wireguard setup is complete. Note wireguard is a silent protocol and it may or may not work, without giving any error message. Typically i/o timeout errors indicate the wireguard connection is not working.
2026-09-07T13:05:04Z INFO [MTU discovery] finding maximum MTU, this can take up to 6 seconds
2026-09-07T13:05:04Z INFO [MTU discovery] reverting VPN interface tun0 MTU to 1320 (due to: ICMP path MTU discovery: finding IPv4 next hop MTU to 1.1.1.1: checking next-hop-mtu found: ICMP Next Hop MTU is too high: 1480 is larger than physical link MTU 1440)
2026-09-07T13:05:04Z INFO [dns] DNS server listening on [::]:53
2026-09-07T13:05:04Z INFO [dns] ready and using DNS server with dot upstream resolvers
2026-09-07T13:05:04Z INFO [dns] downloading hostnames and IP block lists
2026-09-07T13:05:05Z INFO [ip getter] Public IP address is 91.148.228.133 (United Kingdom, England, Manchester - source: ipinfo+ifconfig.co+ip2location+cloudflare)
2026-09-07T13:05:05Z INFO [vpn] You are running on the bleeding edge of latest!
2026-09-07T13:05:05Z INFO [dns] leak check report: 104.23.169.40 (20%), 172.71.101.98 (20%), 104.23.167.42 (10%), 104.23.171.40 (10%), 141.101.75.86 (10%), 162.159.112.43 (10%), 172.70.45.99 (10%), 172.71.181.105 (10%)
2026-09-08T01:00:00Z WARN Caught OS signal terminated, shutting down
2026-09-08T01:00:00Z INFO updater ticker: terminated ✔️
2026-09-08T01:00:00Z INFO http server: terminated ✔️
2026-09-08T01:00:00Z INFO dns ticker: terminated ✔️
2026-09-08T01:00:00Z INFO control: terminated ✔️
2026-09-08T01:00:00Z INFO updater: terminated ✔️
2026-09-08T01:00:00Z INFO tickers: terminated ✔️
2026-09-08T01:00:00Z INFO HTTP health server: terminated ✔️
2026-09-08T01:00:00Z ERROR [wireguard] Failed to load updated MTU of device: failed to get MTU of TUN device: no such device
2026-09-08T01:00:00Z INFO vpn: terminated ✔️
2026-09-08T01:00:00Z INFO shadowsocks proxy: terminated ✔️
2026-09-08T01:00:00Z INFO http proxy: terminated ✔️
2026-09-08T01:00:00Z INFO dns: terminated ✔️
2026-09-08T01:00:00Z INFO other: terminated ✔️
2026-09-08T01:00:00Z INFO [routing] routing cleanup...
2026-09-08T01:00:00Z INFO [routing] default route found: interface eth0, gateway 172.19.0.1, assigned IP 172.19.0.2 and family v4
2026-09-08T01:00:00Z INFO [routing] deleting route for 0.0.0.0/0
2026-09-08T01:00:00Z INFO [routing] deleting route for 192.168.111.0/24
@@@
@@@@
@@@@@@
@@@@.@@ @@@@@@@@@@
@@@@.@@@ @@@@@@@@==@@@@
@@@.@..@@ @@@@@@@=@..==@@@@
@@@@ @@@.@@.@@ @@@@@@===@@@@.=@@@
@...-@@ @@@@.@@.@@@ @@@ @@@@@@=======@@@=@@@@
@@@@@@@@ @@@.-%@.+@@@@@@@@ @@@@@%============@@@@
@@@.--@..@@@@.-@@@@@@@==============@@@@
@@@@ @@@-@--@@.@@.---@@@@@==============#@@@@@
@@@ @@@.@@-@@.@@--@@@@@===============@@@@@@
@@@@.@--@@@@@@@@@@================@@@@@@@
@@@..--@@*@@@@@@================@@@@+*@@
@@@.---@@.@@@@=================@@@@--@@
@@@-.---@@@@@@================@@@@*--@@@
@@@.:-#@@@@@@===============*@@@@.---@@
@@@.-------.@@@============@@@@@@.--@@@
@@@..--------:@@@=========@@@@@@@@.--@@@
@@@.-@@@@@@@@@@@========@@@@@ @@@.--@@
@@.@@@@===============@@@@@ @@@@@@---@@@@@@
@@@@@@@==============@@@@@@@@@@@@*@---@@@@@@@@
@@@@@@=============@@@@@ @@@...------------.*@@@
@@@@%===========@@@@@@ @@@..------@@@@.-----.-@@@
@@@@@@.=======@@@@@@ @@@.-------@@@@@@-.------=@@
@@@@@@@@@===@@@@@@ @@.------@@@@ @@@@.-----@@@
@@@==@@@=@@@@@@@ @@@.-@@@@@@@ @@@@@@@--@@
@@@@@@@@@@@@@ @@@@@@@@ @@@@@@@
@@@@@@@@ @@@@ @@@@
2026-09-08T01:00:00Z INFO Shutdown successful
========================================
========================================
=============== gluetun ================
========================================
=========== Made with ❤️ by ============
======= https://github.com/qdm12 =======
========================================Share your configuration
Environment
gluetun version: latest, built 2026-09-01T23:04:47.130Z, commit 0fef7b2
Host kernel: Linux 7.0.0-31-generic (x86_64)
Alpine base: 3.23.5
VPN_SERVICE_PROVIDER: custom
VPN_TYPE: wireguard
Provider: Privado (no official port forwarding support)
qBittorrent image: lscr.io/linuxserver/qbittorrent:latest
Compose File:
services:
gluetun:
image: qmcgaw/gluetun:latest
container_name: gluetun
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
ports:
- 9980:8080 # qBittorrent Web UI
- 54321:54321 # Torrent listening port (TCP)
- 54321:54321/udp # Torrent listening port (UDP)
environment:
- WIREGUARD_IMPLEMENTATION=userspace
- VPN_SERVICE_PROVIDER=custom
- VPN_TYPE=wireguard
- WIREGUARD_PRIVATE_KEY=
- WIREGUARD_PUBLIC_KEY=
- WIREGUARD_ADDRESSES=100.64.141.217/32
- VPN_ENDPOINT_IP=91.148.228.128
- VPN_ENDPOINT_PORT=51820
- WIREGUARD_PERSISTENT_KEEPALIVE_INTERVAL=10s
- HTTPPROXY=off
- SHADOWSOCKS=off
- FIREWALL_OUTBOUND_SUBNETS=192.168.111.0/24
- FIREWALL_INPUT_PORTS=8080,54321
restart: unless-stopped
qbittorrent:
image: lscr.io/linuxserver/qbittorrent:latest
container_name: qbittorrent
network_mode: service:gluetun
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/London
- WEBUI_PORT=8080
volumes:
- /opt/docker/appdata/qbittorrent:/config
- /mnt/DataStore:/downloads
depends_on:
gluetun:
condition: service_healthy
restart: true
restart: unless-stopped
networks: {}Source: passteque/gluetun