Troubleshooting¶
Firewall stuck after a crash¶
If nym-vpnd crashes with the kill-switch on, its firewall policy remains loaded. WAN traffic
outside the policy's exceptions stays blocked until the daemon recovers. DNS availability
depends on the active policy and resolver configuration; it is not a reliable crash indicator.
To restart the daemon while keeping protection enabled:
To stop the VPN and restore ordinary WAN access:
Explicit Stop removes protection after the daemon exits; Restart preserves it. Procd also respawns crashed processes. If Stop cannot remove protection, check the runtime directory as described below. Deleting individual firewall chains is not a lasting recovery: a daemon policy update or firewall reload can restore them.
Upgrade interrupted half-way¶
If the package manager is killed during an upgrade (power loss, a closed
SSH session without nohup, an OOM kill), the new files may already be on
disk while the package database still records the old version, and
opkg configure does nothing because no package is in the "unpacked" state.
The upgrade hooks are designed to preserve the enabled kill-switch, but the daemon's state
depends on where the interruption occurred. Recovery is to run the same install command again (opkg install <file>.ipk or
apk add --allow-untrusted <file>.apk): it completes the transaction and
restarts the daemon through the new init script. The packet-level test suite exercises
interrupted upgrades in 08-interrupted-upgrade (opkg) and 18-upgrade-interrupted-apk (apk).
Kill-switch stays on after nym-vpnd stop¶
An explicit Stop normally removes protection and writes a stop marker in
/var/run/nym-firewall/. The directory must be owned by root, mode 0700, and not a symlink.
If it is untrusted, Stop cannot write the marker. On fw4, Stop can still remove the tables,
but the next firewall reload installs a boot block. On fw3, teardown cannot safely take the
state lock, so existing protection remains.
For an otherwise valid root-owned directory with the wrong mode, restore it with
chmod 0700 /var/run/nym-firewall. Then run /etc/init.d/nym-vpnd stop again if you intend to
open WAN access, or /etc/init.d/nym-vpnd start to restore VPN service. Reloading the firewall
alone does not create the missing stop marker. If ownership or the path itself is wrong,
repair that first rather than trusting files in the directory.
"No related RPC reply" on GL.iNet devices¶
GL.iNet routers serve their admin panel through nginx on port 80, and nginx does not proxy
/ubus — the endpoint LuCI uses for RPC. Open the app on port 80 and every RPC call gets an HTML
redirect where JSON was expected. The daemon is fine; only the web transport is broken.
LuCI has its own uhttpd port (default 8080/8443) which serves /ubus correctly:
If it is not listening there:
uci set uhttpd.main.listen_http='0.0.0.0:8080'
uci set uhttpd.main.listen_https='0.0.0.0:8443'
uci commit uhttpd
/etc/init.d/uhttpd restart
Upgrade from the LuCI Software page never finishes¶
Reported against packages up to 1.34.0: System → Software → Upgrade sits on "Executing package
manager", and when the dialog finally goes away LuCI wants a new login — while
opkg upgrade nym-vpn or apk upgrade nym-vpn from a shell works. Those packages restarted rpcd
from their post-install step. LuCI runs opkg and apk through rpcd, so the restart cut off the
reply the page was waiting for and dropped every login session. The upgrade itself normally went
through; check with
Newer packages refresh rpcd only after the package manager process has exited, so the page gets its result. Being asked to log in again after an upgrade that changed the web UI's permissions is expected.
Two limits apply to any large package installed from LuCI, not just this one: LuCI stops waiting
for a package operation after 20 seconds and reports XHR request timed out, and rpcd kills the
wrapper it launched after 30 seconds by default (rpcd.@rpcd[0].timeout). The package manager
itself keeps running in both cases — nym-vpn is a 15–30 MB download written to flash, which can
take longer than that on a slow router or link. Wait a minute, reload the page and check the
installed version as above.
Not enough disk space¶
Installed size is roughly 18–36 MB — nym-vpnd is 16–33 MB depending on architecture, nym-vpnc
another 2–3 MB. Devices with a small RAM-backed /tmp may not have room to stage the package.
Free some up:
Don't stage the package on the overlay (/overlay/tmp or similar): that puts a third copy of the
daemon on flash.
Upgrading with little flash¶
opkg stops the daemon once the package is downloaded, so an upgrade needs room for one copy of
nym-vpnd. The kill-switch stays armed until the new daemon starts.
apk writes the new file before it removes the old one, so it needs room for both. If they don't
fit, it fails with No space left on device and keeps the old version. Then upgrade by hand:
download first, while the tunnel is up, and delete the old binary before installing. shutdown
keeps the kill-switch armed, so the router stays blocked until the new daemon starts.
cd /tmp && apk update && apk fetch nym-vpn
/etc/init.d/nym-vpnd shutdown
rm /usr/sbin/nym-vpnd
apk add --allow-untrusted /tmp/nym-vpn-*.apk && rm -f /tmp/nym-vpn-*.apk
sed -i 's/^nym-vpn[<>=~].*$/nym-vpn/' /etc/apk/world
The last line matters: installing a local file pins the package to it, and apk upgrade would
skip later releases.
If the install fails, /etc/init.d/nym-vpnd stop opens the router again.
Not enough RAM (OOM crash)¶
NymVPN needs roughly 80–100 MB. At 128 MB total you can hit OOM, most often at the moment both WireGuard tunnels start.
Fix it with zram — compressed swap in RAM, which roughly doubles what you can use:
zram-swap starts on boot from its own init script once installed:
File-based swap (swapon /path/to/swapfile) does not work on the UBIFS/JFFS2 filesystems
OpenWrt normally uses. zram is the option.
Custom DNS setting has no effect¶
Custom DNS is enabled in the web UI (or nym-vpnc dns get says so), but lookups clearly go
elsewhere — a leak test names your ISP's resolver, or one you never configured.
Check whether dnsmasq is ignoring its resolv file:
If that prints 1, the daemon has deliberately stepped aside. The same setting in LuCI is
Network → DHCP and DNS → Resolv & Hosts Files → "Ignore resolv file" (labelled just DNS on
some versions).
The reason: the daemon applies VPN DNS servers by writing them into dnsmasq's resolv file, which is the only way to change upstreams without restarting dnsmasq — and a restart means several seconds with no DNS for the whole network on every connect. With "Ignore resolv file" ticked, dnsmasq never reads that file, so nothing written there can take effect. Your entries under Forwards are what resolve instead.
Usually that is correct and intended. AdGuard Home, https-dns-proxy and stubby all tick this box when installed, because you asked them to own DNS. Leave it alone — those queries still ride the tunnel while connected.
If you did not mean to, untick it:
VPN DNS servers apply from the next connect. Ad-blocking is unaffected either way — it works through separate dnsmasq directives, not upstream servers.
A resolver on your LAN (Pi-hole, AdGuard Home on another box)¶
A custom DNS server with a private address (10/8, 172.16/12, 192.168/16, link-local, IPv6 ULA) is not routed through the tunnel: it is handed to dnsmasq as an upstream and the kill-switch admits it on every interface except the WAN, whether the tunnel is up or down. So a Pi-hole on the LAN keeps answering the router and your clients while connected and while disconnected. While disconnected with the kill-switch on, dnsmasq's upstream list holds only the LAN resolver: the WAN-provided resolvers are rejected by the kill-switch anyway, and listing them would make dnsmasq burn its retries on them first. With the kill-switch off they follow the LAN resolver. The exclusion of the WAN is deliberate: behind another router the upstream gateway is also a private address, and a resolver there would carry every lookup out the ISP path — that one is rejected like any public resolver. The Pi-hole's own upstream queries are ordinary LAN-to-WAN forwards and follow the tunnel rules. If the daemon cannot determine the WAN interface it logs a warning and falls back to admitting the private resolver through the tunnel only.
No internet after clearing DNS forwards¶
You emptied Network → DHCP and DNS → Forwards, perhaps to force DNS through the VPN, and now nothing resolves.
This is the previous entry again: with "Ignore resolv file" ticked, the Forwards list is dnsmasq's only source of upstream servers, so emptying it leaves nowhere to forward to.
Put a forward back, or untick "Ignore resolv file" so dnsmasq falls back to the resolv file. Unticking is the better fix if VPN DNS was the goal, since it also lets the daemon supply the tunnel's servers.