Anyone using Knot-resolver?


Anyone else running Knot-resolver instead of Unbound? I’ve been running it a while now and it’s working very well.

Just curious if anyone else is using it and what kind of config they are using…

Add DNS fallback feature when Unbound or Cloudflare is unavailable

interested in this.
Ive been having problems with unbound so would be interested to know the benefits vs unbound?
And tips on installing / configuring


Add repo and install:

Then I change the listning IP and port:

sudo systemctl edit kresd.socket

I use something like this:

Then I edit /etc/hosts and put “ knot-resolver” so I get a name in the dashboard.

Edit the config file at /etc/knot-resolver/kresd.conf
Start with the defaults they are fine as a starting point, dnssec and stuff is enabled by default.

Enable Knot-resolver, this sets up 2 threads.
sudo systemctl enable --now kresd@1.service kresd@2.service

Check the service:
sudo systemctl status kresd*.service

You might want to add to kresd.conf: verbose(true)
Then set it to false when you know it’s working again.

Knot-resolver on Debian uses the root.key and root.hints from /usr/share/dns which was recently updated on Debian. If you want to automaintain the root anchors you have to give knot-resolver write access to that folder.

I have added some additional tweaks but I don’t know if they are needed, that’s why I asked in the forum. :slight_smile:



Im just wondering now what are the pros / cons versus Unbound?


Well, right off the top of my head, I would say the pros are that they have their own repo for debian and others so it’s always updated and I don’t have to switch to debian unstable to get a newer version like with Unbound. It’s also quite simple to setup and most things are on by default. The caching seems quite good too and survives a reboot. For the cons, I would say the biggest thing is that there aren’t many tutorials to be found on the net.


yeah, the lack of tutorials, or really any evidence of its wider spread usage is somewhat off putting for me.
There doesn’t seem to be a great deal of good documentation either


It’s one of the more well known resolvers, they also make an authorative dns server. I think Cloudflare use it for their dns servers, not sure though.

Plenty of docs:


yeah just found the docs, sorry.
Id like to give it a try, but im not overly confident in my abilities, even after reading some of the docs.


I have several Raspberry Pi’s so I always setup a new one when trying out something new. Otherwise you could get another SD-card so you can easily go back to the old one?

It’s not harder than setting up Unbound though, probably easier.


yeah I have a spare Pi I think, may have a play.

Why is this required? Does using Knot hinder the usage stats, and / or client name displaying?


No, I just want it to say knot-resolver instead of just localhost in “queries answered by” on the dashboard. It is certainly not required.


Compile unbound from source, instructions here, no need to switch to unstable…

Are you willing to share your configuration file, so we can have a look at the tweaks?


Thanks, I didn’t think it would be that “easy” compiling it myself. Not sure why it’s taking so long getting 1.9.1 into testing/unstable, are they waiting for Buster?

Sure, I can share my kresd.conf, pretty sure it’s not perfect though. The last part is from when I experimented with DoT.

– Load useful modules
modules = {
‘serve_stale < cache’,
‘workarounds < iterate’,

net.ipv6 = false

– Auto-maintain root TA

– Root hints
hints.root_file = ‘/var/lib/knot-resolver/root.hints’

– Cache size
cache.size = 200 * MB

– Prefetch learning (30-minute blocks over 24 hours)
predict.config({ window = 30, period = 48})

– Verbose logging to syslog


– Forward queries encrypted to Cloudflare DoT
– {‘’, hostname=‘’, ca_file=tls_bundle},
– {‘’, hostname=‘’, ca_file=tls_bundle}


How about adding:

      ['.'] = {
              url = '',
              ca_file = '/etc/ssl/certs/ca-certificates.crt',
              interval = 86400  -- seconds

corrected the path of the ca_file.
from ca_file = '/etc/pki/tls/certs/ca-bundle.crt',
to ca_file = '/etc/ssl/certs/ca-certificates.crt',

reference for prefill here.
reference for ca-file here.

the equivalent in unbound (you need the compiled version) is:

	name: "."
	fallback-enabled: yes
	for-downstream: no
	for-upstream: yes
	zonefile: "/"

Knot-resolver stores the data in the cache, whereas unbound stores the data in a file.

My goal is to run unboud (compiled version) and knot-resolver, both serving pihole-FTL (already works on my test pi).
pihole-FTL will than decide, based on the built in algorithm, witch resolver is the fastest and use it for a while. If unbound OR knot-resolver gets into trouble (doesn’t work anymore), pihole-FTL will use the other available resolver.

To achieve this, I simply removed all server entries from /etc/dnsmasq.d/01-pihole.conf and added /etc/dnsmasq.d/04-servers.conf, content:

# unbound
# knot-resolver

I assume you got some of the configuration changes you made here. If you have a better information source, please let us know.


I briefly tried the prefill module but I couldn’t get it to work, that was in the beginning though so I might give it another try. Thanks, this is exactly why I started this thread! :slight_smile:

Interesting idea running both Unbound and Knot in parallell, let me know how it turns out!

That’s right, that tutorial on Knot was the one that got me started. Only one I could find to be honest, I’m surprised there aren’t more out there. I’ll let you know if I find others. Oh and I got some pointers from someone on Reddit too…


EDIT: I tried prefill but get this error…

May 10 14:55:36 pihole systemd[1]: Starting Knot Resolver daemon…
May 10 14:55:37 pihole kresd[399]: [ ta ] warning: overriding previously set trust anchors for .
May 10 14:55:37 pihole systemd[1]: Started Knot Resolver daemon.
May 10 14:55:37 pihole kresd[399]: [prefill] downloading root zone…
May 10 14:55:37 pihole kresd[399]: [prefill] cannot download new zone (/usr/lib/knot-resolver/kres_modules/prefill.lua:88: [prefill] fetch of failed: temporary failure in name resolution), will retry root zone download in 09 minutes 54 seconds
May 10 14:55:37 pihole kresd[399]: [ta_update] refreshing TA for .
May 10 14:55:43 pihole kresd[399]: [ta_update] key: 20326 state: Valid
May 10 14:55:43 pihole kresd[399]: [ta_update] next refresh for . in 12 hours


I don’t really know if using the prefill module will benefit your configuration. You are using cloudflare, so the DNS request will always be completely resolved by cloudflare.
If you are querying (with the cloudflare setup active), you are asking cloudflare to resolve cloudflare will do that, and immediately send you the resulting IP address.
The downside is that cloudflare knows you visited (and every other site you visit).

By using the recursive approach (described for unbound here), only the targeted DNS server will know this. e.g. if you visit, google will know you where there, but if you visit, google will never know, and of course visa versa.
If you use a recursive approach, this is what I think happens:

  • client queries
  • pihole-FTL sends the request (if NOT cached OR blocked) to knot-resolver.
  • knot-resolvers asks the root server: who serves net (wouldn’t do that with prefill, would already know this - cached)
  • root server replies: net is served by DNS server x.x.x.x
  • knot-resolver asks server x.x.x.x: who serves
  • server x.x.x.x replies: is served by DNS y.y.y.y
  • knot-resolver asks server y.y.y.y: what is the IP for
  • server y.y.y.y replies: IP for is
  • knot-resolver replies to pihole-FTL: A
  • pihole-FTL replies to client: A

I hope these steps are correct, that is how I always thought it works.

You may think this is overly complex, but if you use cloudflare, the same thing happens, it isn’t the knot-resolver making all those queries, cloudflare will do this, you just don’t see these requests.

The advantage is obviously privacy. server y.y.y.y will only see the requests to, but doesn’t know about any other sites. When using cloudflare, they have your complete browsing history.


I’m not using forwarding, thoses lines are commented out. I only tried it once and then left it commented for reference… :slight_smile:

EDIT: I changed my Pi-hole DNS to cloudflare in the dashboard and then it work. I suppose it needs another DNS than itself when downloading root zone? I will see what happens in a day when it refreshes…


I had a similar problem:

May 10 15:40:16 raspberrypi kresd[27105]: [prefill] downloading root zone...
May 10 15:40:17 raspberrypi kresd[27105]: [prefill] cannot download new zone (/usr/lib/knot-resolver/kres_modules/prefill.lua:88: [prefill] fetch of `` failed: error loading CA locations (No such file or directory)), will retry root zone download in 09 minutes 52 seconds

solved, reference here.

replace the line

ca_file = '/etc/pki/tls/certs/ca-bundle.crt',


ca_file = '/etc/ssl/certs/ca-certificates.crt',


May 10 15:46:41 raspberrypi kresd[28519]: [prefill] downloading root zone...
May 10 15:46:44 raspberrypi kresd[28519]: [prefill] saving root zone...
May 10 15:46:44 raspberrypi kresd[28519]: [prefill] root zone successfully parsed, import started
May 10 15:46:44 raspberrypi kresd[28519]: [prefill] root zone refresh in 23 hours 59 minutes

also added the following:

  [''] = { '2001:7fe::53', '' }

reference, again here (You can also use the module to change the root hints; they are used as a safety belt or if the root NS drops out of cache).
You should probably select a root server near by, select one here.


Thanks but my ca_file is correct, my error was name resolution error. When I changed the dns on the pihole dashboard to it worked. Not sure why, you’re running it on a pihole too right?

I have downloaded the hints file and point to it in my kresd.conf because the debian one was old before the last update.
hints.root_file = ‘/var/lib/knot-resolver/root.hints’

Do I still need this then?

  [''] = { '2001:7fe::53', '' }

Also when I reboot and check the status of the service I get this, any idea why?

Warning: kresd@1.service changed on disk. Run ‘systemctl daemon-reload’ to reload units.


Whenever you change something in /lib/systems/system, systemctl will notice that and generate the warning. just run sudo systemctl daemon-reload ant the warning will go away.

The reference says: You can also use the module to change the root hints; they are used as a safety belt or if the root NS drops out of cache. I suppose it doesn’t hurt to have the entry, but, also new to this, not sure