Expected Behaviour:
Pihole resolves DNS, and the Pihole admin is accessible
- Ubuntu Linux
- Oracle Cloud - Micro Instance
- Unbound as a DNS resolver
- Wireguard (split tunnel) for DNS resolution for clients (iDevices, Android Phones, Windows Laptop)
Actual Behaviour:
The Pihole randomly stops responding to DNS queries. Most of the time, a restart is required to fix the DNS resolution. At other times, I think it automatically fixes and starts resolving.
-
DNS stops responding (including
dig @127.0.0.1) -
Pi-hole Admin UI becomes inaccessible
-
FTL process remains running
Some observations (based on checks I performed)
Observations
-
ssh to the server works fine
-
tcpdumpshows DNS packets arriving onwg0andlo -
ss -lupnconfirms FTL is listening on:53 -
dig to 127.0.0.1:53 (FTL) times out, while dig to 127.0.0.1:5335 (unbound) works normally -
echo ">stats" | nc 127.0.0.1 4711returns nothing when broken -
straceshows FTL stuck innanosleeploop:
ubuntu@pihole-vpn:~$ sudo strace -p $(pidof pihole-FTL)
strace: Process 75885 attached
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
nanosleep({tv_sec=0, tv_nsec=10000000}, 0x7fff67daf770) = 0
ubuntu@pihole-vpn:~$ dig @127.0.0.1 google.com
;; communications error to 127.0.0.1#53: timed out
;; communications error to 127.0.0.1#53: timed out
;; communications error to 127.0.0.1#53: timed out; <<>> DiG 9.18.39-0ubuntu0.24.04.3-Ubuntu <<>> @127.0.0.1 google.com
; (1 server found)
;; global options: +cmd
;; no servers could be reached
ubuntu@pihole-vpn:~$ dig @127.0.0.1 -p 5335 google.com; <<>> DiG 9.18.39-0ubuntu0.24.04.3-Ubuntu <<>> @127.0.0.1 -p 5335 google.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 21161
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;google.com. IN A;; ANSWER SECTION:
google.com. 30 IN A 142.251.220.110;; Query time: 79 msec
;; SERVER: 127.0.0.1#5335(127.0.0.1) (UDP)
;; WHEN: Mon Mar 30 09:47:11 UTC 2026
;; MSG SIZE rcvd: 55ubuntu@pihole-vpn:~$

