Skip to content

Troubleshooting

Alexander Zinchenko edited this page Jun 22, 2026 · 1 revision

Connection Problems

VPN won't connect

Symptoms: Container starts but the tunnel never comes up, or it crash-loops.

Check:

  1. Token: Verify TOKEN is a valid, unexpired NordVPN access token. CRITICAL: TOKEN is not set or could not obtain WireGuard private key from NordVPN API means the token is missing/invalid. See Getting a Token.
  2. Logs: docker logs vpn — look for the [VPN-CONFIG] and [SERVICE-NORDVPN] lines.
  3. API access: The container needs HTTPS access to NordVPN API IPs during bootstrap. Behind a corporate proxy/firewall, ensure TCP/443 to the NORDVPNAPI_IP addresses is allowed.
  4. TUN device: Ensure --device /dev/net/tun is set and the device exists on the host.
  5. Capabilities: WireGuard needs NET_ADMIN, plus SYS_ADMIN and net.ipv4.conf.all.src_valid_mark=1 (or privileged: true) so wg-quick can set its routing policy.

VPN connected successfully but no traffic

Symptoms: wg0 exists but nothing flows.

Check:

  1. Handshake: docker exec vpn wg show wg0. If you see 0 B received and no latest handshake, the NordLynx handshake isn't completing — usually a transient/overloaded server or rate-limiting. Wait for the health/scheduled reconnect, or restart to pick a new server.
  2. Firewall: docker exec vpn iptables -S OUTPUT — verify the -o wg0 -j ACCEPT rule exists.
  3. Diagnostics: docker exec vpn /usr/local/bin/network-diagnostic

Connection drops frequently

Fix: Use health monitoring and scheduled switching:

environment:
  - CHECK_CONNECTION_CRON=*/5 * * * *
  - CHECK_CONNECTION_URL=https://1.1.1.1
  - RECREATE_VPN_CRON=0 */6 * * *

See Automatic Reconnection for details.

Networking Problems

Containers behind VPN have no network

Symptoms: docker exec app curl https://example.com fails.

Check:

  1. VPN is up: docker exec vpn wg show wg0 — confirm a recent handshake.
  2. DNS: docker exec vpn cat /etc/resolv.conf — should list the VPN DNS servers the container wrote (default 103.86.96.100 / 103.86.99.100, or your DNS override). See Custom DNS.
  3. Firewall: docker exec vpn iptables -S — verify the OUTPUT chain allows traffic via wg0.

Can't access containers from LAN

Fix: Set NETWORK to include your LAN CIDR:

-e NETWORK=192.168.1.0/24

Docker subnets are not auto-allowed. If inter-container communication is needed, include Docker's subnet too.

DNS leaks

Check:

  1. Run diagnostics: docker exec vpn /usr/local/bin/network-diagnostic
  2. Look at the DNS section — nameservers should be VPN-provided addresses, reached over wg0
  3. If using IPv6, it may bypass the VPN. See IPv6 Configuration

NETWORK setting defeats the kill switch

Cause: NETWORK CIDRs are always allowed, regardless of VPN state. If you set NETWORK=0.0.0.0/0, all traffic bypasses the VPN.

Fix: Keep NETWORK as narrow as possible — only include your LAN subnet and any Docker networks that need direct access.

Firewall & Permissions

iptables errors on container start

Symptoms: Errors like iptables: No chain/target/match by that name or Permission denied.

Check:

  1. NET_ADMIN capability: Ensure --cap-add=NET_ADMIN is set.
  2. Kernel compatibility: The container auto-detects nft vs legacy. Check logs for [ENTRYPOINT] Using IPv4 backend: to see which was selected.
  3. Host iptables/WireGuard modules: Some minimal hosts (e.g., certain NAS devices) may lack required kernel modules.

wg-quick fails to set routing / src_valid_mark

Add the SYS_ADMIN capability and net.ipv4.conf.all.src_valid_mark=1 sysctl (or run privileged: true). See the compose snippet in Docker Compose Examples.

Scheduling

Cron jobs not running

Check:

  1. Syntax: Valid cron format (5 fields). Invalid expressions are silently ignored by crond.
  2. Logs: Look for [INIT-SETUPCRON] lines at startup — they show the parsed schedule in human-readable format.
  3. Crontab: docker exec vpn cat /var/spool/cron/crontabs/root

Diagnostics

Built-in Network Diagnostics

Enable automatic diagnostics on every VPN connection:

-e NETWORK_DIAGNOSTIC_ENABLED=true

Or run manually:

docker exec vpn /usr/local/bin/network-diagnostic          # full diagnostics
docker exec vpn /usr/local/bin/network-diagnostic --basic   # IP + location only

The diagnostic tool checks: public IP and geolocation, WireGuard status, network interfaces, firewall rules, DNS nameservers, IP routing table, and kernel version.

Reading Container Logs

docker logs vpn              # full logs
docker logs -f vpn           # follow in real-time
docker logs --tail 50 vpn    # last 50 lines

Key log messages:

Log message Meaning
[ENTRYPOINT] Using IPv4 backend: ... Firewall backend selected
[VPN-CONFIG] Selected server ... Selected VPN server
[SERVICE-NORDVPN] VPN connected successfully wg0 came up (verify with a handshake)
[SERVICE-NORDVPN] VPN connection timeout Tunnel didn't establish in time
[HEALTHCHECK] Connection check failed Health check triggered reconnection

Inspecting the Container

docker exec vpn wg show wg0                  # WireGuard peer/handshake/transfer
docker exec vpn ip route                     # view routing table
docker exec vpn iptables -S                   # check iptables rules
docker exec vpn cat /etc/resolv.conf          # active DNS servers
docker exec vpn env | sort                    # check environment

Clone this wiki locally