Writing this up because I burned a lot of hours chasing the wrong
things, and every search result pointed me at router firmware. Posting
the full trail so the next person (or their AI assistant) finds it.
## Symptoms
Random websites and apps would stop loading on any client, WiFi or
wired. Google Maps, Reddit, drive.google.com, Amazon Alexa, Pinterest,
iCloud. Toggling WiFi off/on or unplugging the LAN cable fixed it for
about a minute, then a different site would break. Over my WireGuard
VPN the problem never appeared. This went on for weeks.
## Setup
– Router: GL.iNet Flint 3e (GL-BE6500), firmware 4.9.0, OpenWrt 23.05
– Server: Lenovo ThinkCentre M90q Gen 2, i5-11500, 16GB, Ubuntu 26.04
– AdGuard Home v0.107.78 in Docker on the server, port 53
– Upstream was DoH to CIRA Canadian Shield, bootstrap Quad9
– WireGuard via systemd wg-quick on the server, not on the router
– Router hands out the server IP as DNS via DHCP option 6
– WAN: DHCP, public IP, no CGNAT
## Things I tried that were all wrong
– Disabled MLO. No change.
– Set WAN MTU to 1300 per a GL.iNet forum thread. No change (that fix
is for PPPoE lines, mine is DHCP).
– Tuned ARP timeouts on the router. Apparent improvement was a
coincidence; the commands were below an `exit 0` in rc.local so they
never ran on boot anyway.
– Checked conntrack. 536 of 28672. Not the issue.
– Disabled Qualcomm NSS Network Acceleration. This is a real known bug
class on Flint 3 (breaks NAT loopback, causes timeouts on wired
clients) but it was not my problem. I turned it back on afterwards.
– Checked IPv6. My router had IPv6 disabled on WAN entirely, so Happy
Eyeballs was never involved.
– Removed an iptables DNAT rule I had in rc.local that hijacked all
client DNS to the server. This WAS broken (DNAT to a host in the same
subnet without SNAT means the reply comes from an unexpected source
IP and the client drops it) but removing it did not fix the main
symptom. Worth removing anyway. Bonus: on this firmware the real
ruleset is nftables/fw4, so those legacy iptables rules were running
in a parallel stack with unpredictable ordering.
– Paused AdGuard Home protection. Sites still broke, so I crossed
AdGuard off the list. THIS TEST WAS WORTHLESS. The Protection toggle
disables filtering, not the DNS server. Queries still went through
AdGuard to the same upstream. If your problem is upstream, this test
will never catch it.
## How I actually found it
I ran a loop on two machines on the same LAN:
while true; do while read d; do r=$(curl -s -o /dev/null -m 8 -w "%{http_code} dns=%{time_namelookup} tot=%{time_total} err=%{errormsg}" "https://$d") case "$r" in 000*) echo "$(date '+%H:%M:%S') FAIL $d $r" echo " sys: $(dscacheutil -q host -a name $d | grep ip_address | head -2 | tr '\n' ' ')" echo " direct: $(dig +short $d @<ADGUARD_IP> | head -2 | tr '\n' ' ')" ;; esac done < /tmp/domains.txt sleep 20 done
The key output when it failed:
FAIL drive.google.com 000 dns=0.000000 tot=0.001336 err=Could not resolve host sys: direct: 142.251.46.78
dns=0.000000 and a 1.3ms total means curl never even tried. The system
resolver returned an instant negative from cache, while a direct dig to
AdGuard answered fine. So the resolver had given up on my DNS server.
Then I read the AdGuard container logs:
docker logs --tail 200 adguardhome 2>&1 | grep -i -E "timeout|upstream|bootstrap"
Dozens of these per hour:
[error] dnsproxy: exchange failed upstream=https://protected.canadianshield.cira.ca:443/dns-query question=";drive.google.com. IN A" duration=9.35ms err="...: unexpected EOF"
And the list of affected domains in the log was exactly my list of
broken apps: drive.google.com, www.amazon.ca, api.amazonalexa.com,
reddit.map.fastly.net, icloud.com, api.facebook.com, i.instagram.com,
ocsp2.apple.com, atv-ps.primevideo.com.
"unexpected EOF" means the provider tears down the HTTPS connection
mid-request. Not a timeout, not NXDOMAIN. The client gets nothing,
macOS mDNSResponder caches the failure, the app hangs. Toggling the
interface flushes that cache, which is why it "fixed" things for a
minute.
Why it never happened over VPN: my tunnel pushes its own DNS, so the
broken upstream was out of the path.
## The fix
In AdGuard Home, Settings > DNS settings:
– Removed the CIRA Canadian Shield DoH upstream entirely
– Upstreams now: https://dns.quad9.net/dns-query,
https://dns.cloudflare.com/dns-query, 9.9.9.9
– Upstream mode: parallel (queries all upstreams at once, takes the
first answer, so one bad upstream cannot stall anything)
– Fallback DNS: 1.1.1.1 and 8.8.8.8 (plain DNS, no TLS handshake to
fail on)
– Upstream timeout: 3s instead of the 10s default
Then on the router I handed out a second DNS server via DHCP so clients
have somewhere to go if the AdGuard host is down:
uci add_list dhcp.lan.dhcp_option='6,<ADGUARD_IP>,<ROUTER_IP>' uci commit dhcp /etc/init.d/dnsmasq restart
Error count went from dozens per hour to zero.
## Two side issues I found along the way
-
Steven Black's List blocks ct.pinterest.com and trk.pinterest.com.
The Pinterest iOS app waits on those synchronously and never renders.
Browser worked fine, app did not. If a specific app hangs while its
website works, check your AdGuard query log filtered by that client
before blaming the network.
-
Separate real firmware bug on Flint 3e 4.9.0: port forwards created
in the GUI are stored in /etc/config/port_forward with enabled '1'
but are never applied to the live ruleset. `nft list chain inet fw4
dstnat_wan` was empty. This silently killed my WireGuard server. The
workaround is to create the rule directly in /etc/config/firewall
with uci, which does get applied. Reported to GL.iNet.
-
Unrelated but it cost me an hour: my WireGuard client config had a
hardcoded Endpoint IP from months earlier. My ISP had changed the
WAN address. Always use your DDNS hostname, never a literal IP.
## TL;DR
If random sites and apps break on all your devices and nothing in your
router config explains it, read your DNS resolver's logs before
touching firmware. Pausing AdGuard protection does not test the
upstream path. A DoH provider that drops connections looks exactly like
a broken router.
Source: r/AdGuardHome · by /u/Abject_Gate_797