Tutorial

Root DNSSEC KSK rollover: check your validating resolver

Security & Monitoring12 min read14 steps

Since October 11, 2026, the DNS root zone has been signed by a new key, KSK-2024, with key tag 38696. A validating resolver that does not know this key can no longer build the DNSSEC chain of trust: it answers SERVFAIL, even for names that resolve elsewhere, and the outage looks like a network failure. This guide shows how to check the trust anchor of Unbound, BIND, Knot Resolver, systemd-resolved and dnsmasq in ten minutes, prove it with `dig` and `delv`, then fix it.

Contents· What changed on October 11, 20261/12
  1. 01What changed on October 11, 2026
  2. 02Key takeaways
  3. 03Domain owner or server administrator: who needs to act
  4. 04Diagnostic prerequisites
  5. 05Diagnose your resolver in seven steps
  6. 06Where the trust anchor lives, resolver by resolver
  7. 07Fix it for your resolver
  8. 08After the fix: what to watch
  9. 09Do not turn validation off to silence the error
  10. 10Troubleshooting: the messages you will see
  11. 11Error messages and fixes
  12. 12In short

What changed on October 11, 2026

DNSSEC relies on a single root of trust: the key signing key (KSK) of the root zone. Every validating resolver keeps a local copy of it, called a trust anchor, and checks everything else from there. According to IANA, KSK-2024 (key tag 38696) was published in the root zone on January 11, 2025, then started signing the root on October 11, 2026, replacing KSK-2017 (key tag 20326).

On October 15, 2026, ICANN announced that the key rollover had completed as planned. The announcement mentions reports affecting a limited number of systems and states that ICANN is still assessing whether they are related to the change: it gives neither a number nor a cause, and this guide does not suggest one. The schedule is not over: IANA plans to revoke KSK-2017 on January 11, 2027, then remove it from the zone on March 22, 2027.

Key takeaways

  • The key to look for — KSK-2024, key tag 38696, algorithm 8 (RSA/SHA-256). The previous one, KSK-2017, has key tag 20326.
  • The symptom — a resolver that only trusts 20326 can no longer validate the root. Verisign and ICANN warn that it then fails to resolve, whether the requested name is signed or not.
  • The normal mechanism — RFC 5011 lets a resolver adopt a new key on its own after observing it for 30 days, provided it is running and can write its anchor file.
  • The risky cases — a system image or snapshot older than the key, a read-only anchor file, a static anchor in dnsmasq or in BIND.
  • What does not change — your domain's DS record at the registry: the change concerns the root key, not your zone's key.
  • What comes next — revocation of KSK-2017 planned for January 11, 2027, removal on March 22, 2027. A resolver that already trusts 38696 validates the root signed with that key.

Domain owner or server administrator: who needs to act

Two roles are often confused in support tickets. The owner of a signed domain publishes a DS record at the registry, pointing to the key of THEIR zone. That DS does not depend on the root key: there is nothing to change for this rollover, neither in the example.com zone nor at your registrar. If you only manage your records (see adding a DNS record), you are not affected.

The administrator of a server running a validating resolver is. Unbound behind a mail server, BIND on a monitoring host, Knot Resolver in a container, systemd-resolved with DNSSEC enabled, dnsmasq or Pi-hole with validation turned on: each one carries its own anchor. On a VPS where you have root access, that administrator is you. A server that simply forwards its queries to a public resolver without validating itself depends on that resolver's anchor, not its own.

Diagnostic prerequisites

Plan ten minutes and root or sudo access to the server. Two tools are enough: dig and delv, provided on Debian and Ubuntu by the bind9-dnsutils package (sudo apt install bind9-dnsutils), and on AlmaLinux or Rocky Linux by bind-utils. No particular resources are needed: the queries weigh a few kilobytes.

Note the listening address of your resolver, usually 127.0.0.1, or 127.0.0.53 for systemd-resolved, and keep the address of a validating public resolver for comparison, for example 9.9.9.9. The outputs described below are examples of shape, not measurements of your server: only the named fields matter. The tests target the root and com., two signed zones, so they do not depend on any particular domain.

Diagnose your resolver in seven steps

  1. Identify the resolver that answers

    cat /etc/resolv.conf shows the address the system queries, resolvectl status tells you whether systemd-resolved sits in between, and sudo ss -lunp 'sport = :53' names the process listening on port 53: unbound, named, kresd, dnsmasq or pihole-FTL. That is the process you are going to examine.

  2. Query the root with dig +dnssec

    Run dig +dnssec . SOA @127.0.0.1, then dig +dnssec com. SOA @127.0.0.1. Look at two header fields: status: and flags:. A status: NOERROR with the ad flag means the answer was validated. A status: SERVFAIL on the root itself is the clearest sign of an outdated anchor.

  3. Isolate validation with +cd

    dig +dnssec +cd com. SOA @127.0.0.1 asks the resolver to answer without validating (checking disabled). If this query returns NOERROR while the previous one fails with SERVFAIL, the network and upstream servers work: DNSSEC validation is what blocks, so the anchor or the clock.

  4. Compare with a validating public resolver

    dig +dnssec com. SOA @9.9.9.9 should return NOERROR with ad. If the public resolver validates and yours does not, the problem is local. Check the server time with timedatectl while you are at it: a skewed clock also makes signature checks fail, and produces the same SERVFAIL.

  5. See which key signs the root

    dig +dnssec +multi . DNSKEY @9.9.9.9 lists the published keys. Those with flag 257 are KSKs; with +multi, dig adds their key id as a comment. In the current phase, KSK-2017 is still published, but the signature (RRSIG) over the key set carries key tag 38696: that is the key your anchor must know.

  6. Read the anchor actually loaded

    Unbound: sudo grep 'id = 38696' /var/lib/unbound/root.key (Debian path; elsewhere, unbound-checkconf -o auto-trust-anchor-file gives yours) must return a line marked VALID. BIND: sudo rndc secroots - must list ./RSASHA256/38696 ; managed, and sudo rndc managed-keys status an entry keyid: 38696 followed by trusted since. Knot Resolver: call trust_anchors.summary() from its control console. dnsmasq: look for a trust-anchor=.,38696,8,2,… line in the loaded configuration.

  7. Confirm with delv

    delv @127.0.0.1 com. SOA validates the answer itself and prints ; fully validated when the chain is complete. Careful: delv uses the anchor compiled into its own binary, not your resolver's. An old delv can therefore fail on its own: update the package before drawing a conclusion about the resolver.

Where the trust anchor lives, resolver by resolver

Scroll the table

ResolverWhere to lookKey update
Unbound`auto-trust-anchor-file` directive (Debian: `/var/lib/unbound/root.key`)RFC 5011 if the file and its directory are writable, otherwise `unbound-anchor`
BIND`rndc secroots -` and `managed-keys.bind`; built-in anchor with `dnssec-validation auto`RFC 5011 with `auto`, `initial-key` or `initial-ds`; none with `static-key`
Knot Resolver`trust_anchors.add_file()` in v5, `dnssec/trust-anchors-files` in v6RFC 5011, unless the file is declared read-only
systemd-resolvedAnchor built into the binary; `*.positive` files in `/etc/dnssec-trust-anchors.d/`None over DNS: an up-to-date systemd package is required
dnsmasq`trust-anchor=` lines in the loaded configurationNone: a static line to edit by hand
Pi-hole v6`/etc/pihole/dnsmasq.conf`, generated by FTLRewritten by FTL, which writes keys 20326 and 38696
delv (tool)Anchor compiled into the binaryUpdate of the package that ships it

Fix it for your resolver

  1. Unbound: refresh the anchor

    Update the system first (sudo apt update && sudo apt upgrade). On Debian, the dns-root-data package provides /usr/share/dns/root.key, and Unbound's startup script copies that file to /var/lib/unbound/root.key when it is newer; version 2024071801~deb12u1 shipped for Debian 12 already contains KSK-2024. Then force a check with sudo -u unbound unbound-anchor -a /var/lib/unbound/root.key -v, followed by sudo systemctl restart unbound. The key built into unbound-anchor includes KSK-2024 since Unbound 1.21.0.

  2. Unbound: make RFC 5011 possible

    If the key is still missing, check that the unbound user can write the file AND its directory: the documentation requires it to create a temporary file. ls -ld /var/lib/unbound /var/lib/unbound/root.key is enough to see it. A file mounted read-only in a container blocks automatic updates without any visible error on the client side.

  3. BIND: auto or declared anchor

    With dnssec-validation auto;, BIND starts from the anchor shipped with the software and keeps it current through RFC 5011 in managed-keys.bind. Update the package, check that managed-keys-directory is writable by named, then run sudo rndc managed-keys refresh. With dnssec-validation yes; and a hand-declared anchor, add the line . initial-ds 38696 8 2 "683D2D0ACB8C9B712A1948B27F741219298D0A450D612C483AF444A4C0FB2B16"; to the trust-anchors block and remove any static-key anchor that only knows 20326.

  4. Knot Resolver: check the anchor file

    Update the package, then look at how the anchor file is declared. When it is read-only (second argument true of trust_anchors.add_file() in v5, read-only: true in v6), the resolver never modifies it: your distribution's package must bring the key. Otherwise, check that kresd can write the file. The documentation states that when the file does not exist, the resolver tries to bootstrap the root anchor itself.

  5. systemd-resolved: update systemd

    systemd-resolved does not update its anchor over DNS: only a package update brings the new key. Upstream code includes it, notably since systemd 256.12 and 257.4, and the current Debian 12 systemd-resolved package contains it too. Check /etc/dnssec-trust-anchors.d/: a *.positive file declaring a root key disables the built-in anchor. Remove it or add key 38696 to it, then run sudo systemctl restart systemd-resolved and resolvectl flush-caches.

  6. dnsmasq: add the static line

    dnsmasq does not implement RFC 5011: the anchor is a fixed line. Add trust-anchor=.,38696,8,2,683D2D0ACB8C9B712A1948B27F741219298D0A450D612C483AF444A4C0FB2B16 next to the 20326 line, then restart the service. On Debian 12, the /usr/share/dnsmasq-base/trust-anchors.conf file from the dnsmasq-base 2.90-4~deb12u2 package only contains key 20326, whereas the Debian 13 one contains both: check which file your configuration actually loads. Pi-hole v6 writes both lines itself into /etc/pihole/dnsmasq.conf when DNSSEC validation is enabled.

  7. Automate it for next time

    An anchor only goes stale on a server that no longer gets updates. Enable automatic security updates for resolver packages (see automatic updates on Debian and Ubuntu) and add a dig +dnssec com. SOA @127.0.0.1 probe to your monitoring that alerts on SERVFAIL. If your local DNS goes through Pi-hole, the Pi-hole v6 on a VPS guide shows how to place Unbound upstream.

After the fix: what to watch

Once the ad flag is back in the answers, three points deserve a check.

Images and snapshots first. A machine restored from an old backup starts again with the anchor file of that time. If the file only knows 20326, RFC 5011 can no longer catch up: it only accepts a new key if the key set is signed by an already trusted key, and the root is no longer signed by 20326. The anchor must then be refreshed by hand, as above.

Container images next. An image built with a static anchor keeps it on every redeployment: rebuild it from an up-to-date base.

Revocation last. On January 11, 2027, KSK-2017 is due to be published with the revoke bit. A resolver following RFC 5011 will mark it as revoked: in Unbound's file, the 20326 line will move to the REVOKED state. That is the expected state, not an outage.

Do not turn validation off to silence the error

Switching to dnssec-validation no, val-permissive-mode: yes or DNSSEC=no makes the SERVFAIL disappear, but also removes all protection against forged answers. Fix the anchor, then test. Never paste a key found on a forum: the authoritative source is https://data.iana.org/root-anchors/root-anchors.xml, whose signature is checked with root-anchors.p7s and icannbundle.pem, published in the same place by IANA. The SHA-256 digest of KSK-2024 appears there: 683D2D0ACB8C9B712A1948B27F741219298D0A450D612C483AF444A4C0FB2B16.

Troubleshooting: the messages you will see

The messages below are taken from the source code or documentation of the software involved. They let you tell an outdated anchor apart from a network problem, a skewed clock or a diagnostic tool that is itself too old. For Unbound, first raise log detail with val-log-level: 2 in the server: section, then restart: every rejected query will be logged with its reason and the server that supplied the faulty data.

Error messages and fixes

  • failed to prime trust anchor -- DNSKEY rrset is not secure (Unbound log, followed by . DNSKEY IN) — Unbound obtained the root keys but could not validate them with its anchor: outdated anchor or wrong clock. Refresh root.key.
  • failed to prime trust anchor -- could not fetch DNSKEY rrset — Unbound does not even get the root keys: network, firewall or UDP fragmentation, not the anchor. Test dig +dnssec . DNSKEY against the upstream server.
  • status: SERVFAIL with +dnssec, NOERROR with +cd — the signature of a validation failure. With ede: yes in Unbound, the client also receives an extended error code (RFC 8914).
  • resolution failed: broken trust chain or no valid RRSIG (delv) — delv could not walk back to a valid anchor. First check that delv itself is up to date.
  • ; initializing managed in rndc secroots - — BIND knows the key but has never confirmed it with a refresh query. Run rndc managed-keys refresh and check permissions on managed-keys-directory.
  • unbound-anchor exits with code 0 without changing anything — according to its manual page, 0 means both "no update needed" and "error". Run it again with -v and reread the file.

In short

The root key rollover asks nothing of domain owners, nor of servers whose packages follow updates. It penalises frozen resolvers: an old image, an anchor file that cannot be written, a static anchor in dnsmasq or BIND. Three actions settle the question: dig +dnssec com. SOA against your resolver, the same query with +cd, then reading the loaded anchor. Keep January 11, 2027 in mind: the revocation of KSK-2017 will show up in your anchor files, and that is an expected state. On a server where you have root access, this check takes ten minutes and can be scheduled once and for all in your monitoring.

Your resolver, your trust anchor

On a ServOrbit.com VPS, you have root access: you choose your system, you update your resolver packages when you decide and you read the validation logs yourself. If you would rather not handle this, the VPS administration option is available.

Need help?

Browse our help center and FAQ, or reach our team — callback, WhatsApp or email. Support in French, English and Arabic.

Message us on WhatsAppopens in a new tab