Can a Pi-hole *receive* DDNS requests

I would like to have redundancy with my Pi-hole but I think this is not readily doable.
My plan is therefore to run the KEA ISC DHCP server on two machines, splitting the served range, and register the leased IP and its name in Pi-Hole (mimicking its default behaviour).

I hope I will be able to directly use KEA's DDNS client (configured as part of its DHCP server), but worst case I will run a DDNS server alongside (I would be grateful for any feedback if someone attempted this with aPi-hole).

The key question is : can a Pi-hole receive DDNS requests and update its internal DNS server?

In other words if I have pihole serving DNS on port 53 and an independent DHCP server that will also update pihole with a new combo myphone → 192.168.10.76, will I be able to query pihole:53 fo the resolution of myphone and get 192.168.10.76?

EDIT: right at the moment when I pushed "publish" I saw there was the same question already, from 2019, but no answers

Redundancy with regard to what?

Two DHCP servers pointing to the same Pi-hole will give you no DNS redundancy.

Both DHCP and DNS.

This would be a setup with two Pi-holes on two different machines receiving DDNS updates from two DHCP servers (each serving half of the range). One machine = DNS + DHCP.

The DHCP DHCPOFFER would send two DNS server IPs, and this would be interpreted a way or another by the client (either as a chain, or as a round robin, or as a fallback).

If a Pi-hole fails (either the service or the server) there would be another source of DHCP and a DNS server with current entries

Today there is no native way to do that AFAIK, a built-in DDNS server and DDNS client would solve the problem, though (that would be awesome)

For DNS redundancy, you could either have your existing DHCP server or Pi-hole's DHCP server hand out two DNS server IPs (via custom dnsmasq configurations).

For local name resolution, you could take advantage of Pi-hole's Conditional Forwarding.

Yes, this is fine.

Would you mind expanding on that a bit? Let's say I have pihole1 and pihole2 serving both DHCP and DNS.

Each would serve half of the IP range, and register locally the hostname for this lease.

Say pihole1 offers 192.168.10.12 to myphone, and registers myphone on its DNS.
How would pihole2 know that they need to query pihole1 if they cannot find myphone in their own DNS? (in the case they are the ones queried, out of the two IPs a LAN client would have)


EDIT: I read about conditional forwarding on my (for now - single) Pi-hole. The description mentions that

A valid config line could look like true,192.168.0.0/24,192.168.0.1,fritz.box

Let's say I serve 192.168.10.0/25 and 192.168.10.128/25 on to two Pi-holes. I would like to have a direct and reverse resolution. Would this work?

true,192.168.10.0/25,192.168.10.1,home.arpa
true,192.168.10.128/25,192.168.10.128,home.arpa

Notably would this send a request to resolve myphone.home.arpa to both 192.168.10.1 and 192.168.10.128? (and get a replay from one of them, and a SERVFAIL (not NXDOMAIN!) from the other)


EDIT: I fear that this will not fly:

root@srv /e/docker# dig @192.168.10.2 imprimante.home.arpa

; <<>> DiG 9.18.33-1~deb12u2-Debian <<>> @192.168.10.2 imprimante.home.arpa
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34747
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;imprimante.home.arpa.          IN      A

;; ANSWER SECTION:
imprimante.home.arpa.   0       IN      A       192.168.10.11

;; Query time: 16 msec
;; SERVER: 192.168.10.2#53(192.168.10.2) (UDP)
;; WHEN: Tue Jul 08 16:30:01 CEST 2025
;; MSG SIZE  rcvd: 65

root@srv /e/docker# dig @192.168.10.2 doesnotexist.home.arpa

; <<>> DiG 9.18.33-1~deb12u2-Debian <<>> @192.168.10.2 doesnotexist.home.arpa
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 2673
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;doesnotexist.home.arpa.                IN      A

;; Query time: 0 msec
;; SERVER: 192.168.10.2#53(192.168.10.2) (UDP)
;; WHEN: Tue Jul 08 16:30:14 CEST 2025
;; MSG SIZE  rcvd: 51

The answer is NXDOMAIN, which is correct but is not the right answer in case of a HA setup (because if I get that first, I will not query the other one - the answer means "host does not exist in my database, and I respond as the main source of truth")

No.

But why would you want to define two forwards?

Are you going to run three Pi-holes?

Maybe a complete example will help to clarify:

  • pihole1 responded to a DHCP request and provided myphone with an IP, and registered myphone in its DNS.
  • pihole2 responded to a DHCP request and provided printer with an IP, and registered printer in its DNS.

I am on a third device mylaptop. I have two IPs in my DNS servers (the ones corresponding to pihole1 and pihole2). I want to query printer.home.arpa

  • if I hit pihole1 I get NXDOMAIN (no such host). Bummer
  • if I hit pihole2 I get a correct resolution and the IP of printer.home.arpa

This is why

  • either the two Pi-hole are synchroinized though an internal mechanism → both have all the leases registered, theirs and the other Pi-hole's
  • or they DDNS when registering a host (after having leased an IP) → both have all the leases registered, theirs and the other Pi-hole's
  • or there is a mechanism to say "I am a Pi-hole and I get a DNS request for the local domain (home.arpa in my case). If I cannot resolve it I will ask the other one (or forward the query to the other one)" → I thought that this was what conditional forwarding is doing, but I do not think it does the "If I cannot resolve" part (or am I mistaken?)

That's confusing.
Your example reads as if you expect to see an NXDOMAIN answer because DNS records are synched?

And it doesn't really explain why you'd want those two forwards for a custom Pi-hole configuration.

Pi-hole would look into its cache and its local definitions before considering to forward to any upstream, including CF.

In case of two Pi-holes, each Pi-hole would need a CF configuration (i.e. one line) pointing to the respective other.

If it doesn't find a local match for a DNS request, it would forward the request upstream (unless configured otherwise)
CF would allow you to configure the correct upstream (public resolvers won't know local names).

EDIT: I should point out that the current dnsmasq that pihole-FTL is based on has an issue with regards to custom forwards.
The issue is currently under investigation by dnsmasq maintainer's.
I'm on the road now - I'll try to link the related topic when stationary.

Ahhhh - this is my answer. Thank you!

My concern was that the conditional forwarding forwards to the target when there is a match on the condition, without consideration for its own database. If it first checks if it can resolve the name, and then forwards this is perfect.

As a side note: I have been reading a lot about HA with Pi-holes, across plenty of forums, blogs etc. There was a general message that Pi-hole is not equipped for such a setup and suggested nebula, keepalive and other solutions.
I will make a PR for the documentation somewhere to maybe highlight this simple solution (once I have implemented it, which is going to be quick)

As someone who has donated to dnsmasq I always feared it being a single dev solution. I love it, I find it really nice and ran it in many occasions on very exotic environments. But I always had this small fear in the back of my head.