DNS servers in 2026: revisit CoreDNS, PowerDNS and BIND 9 before you add another DNS record by hand
In most companies, somebody still adds internal DNS records by hand. A new database gets an IP address, an engineer logs in to the DNS server, types one line into a zone file or a web console, and saves. Most days nothing goes wrong. Then one day the serial number is not changed, or a trailing dot is missing, and half the office reaches the old server while the other half reaches the new one. Nobody can say who changed what.
DNS is old and mostly invisible, so it is rarely revisited. The software under it has not stood still. BIND 9 has a new long-term branch and a busy security year behind it. PowerDNS has moved to 5.x for both its authoritative server and its recursor. CoreDNS, which most people meet only inside Kubernetes, has grown zone transfers, dynamic updates and encrypted transports. And on 11 October 2026 the DNS root zone switched to a new DNSSEC key, which every validating resolver had to trust in advance.
This post compares the main open source DNS servers as they stand on 28 October 2026: CoreDNS, PowerDNS (Authoritative Server, Recursor and, briefly, dnsdist) and BIND 9, with short notes on Knot DNS, Knot Resolver and Unbound. We cover authoritative and recursive roles, licences and support windows, DNSSEC, where zone data lives, zone transfers and TSIG, DNS-as-code, performance and operations, and then work through a plan for one invented team.
A few earlier posts sit close to this one. Kubernetes pod networking with Cilium, Calico and Flannel looked at how packets move inside a cluster; cluster DNS tells them where to go. TLS certificate automation with cert-manager, Certbot and step-ca needed a DNS API for ACME DNS-01 challenges. Mesh VPNs with Headscale, NetBird and plain WireGuard touched on split DNS for private names. And configuration management with Ansible, Salt and Puppet made the point we repeat here: a change typed by hand on a server is a change nobody can review.
A scenario to keep us honest
Take an invented Ranchi company that builds fleet tracking, maintenance and spare parts software for mining contractors and steel plant suppliers in Jharkhand and Odisha. About 25 engineers, with a three-person platform team. Newer services run on a Kubernetes cluster in a Mumbai cloud region; older parts, including an ERP integration and a reporting database, run on virtual machines in a small colocation rack in Ranchi.
Their DNS today:
- Two BIND 9.16 servers in the Ranchi rack, set up in 2020. One is primary for the internal zone
corp.internaland the reverse zones; the other is a secondary fed by zone transfer. Both also act as recursive resolvers for the office and the rack. BIND 9.16 reached end of life long ago. - The internal zone has about 600 records, edited by hand on the primary by whoever needs one. There is no history apart from a few dated
.bakfiles. - The public domain sits at the registrar’s DNS service, edited in its web console by two people sharing one login.
- The Kubernetes cluster runs the CoreDNS it came with, plus one forward rule added during an incident that sends
corp.internalover the VPN to Ranchi. - DNSSEC validation is on in the BIND resolvers because it was the package default. Nobody is sure which trust anchors they hold.
Two things started the discussion. First, during a planned move of the reporting database, an engineer changed its A record on the primary but did not increase the SOA serial. The secondary never picked up the change, and for most of a working day offices using the secondary reached the old database, still running read-only, and a customer saw stale reports. Second, after the root key rollover on 11 October 2026, the security lead asked: “Are our resolvers validating, and did they trust the new root key before the switch?” Nobody could answer.
The proposals came quickly. “We already run CoreDNS in Kubernetes, use it for everything.” “Put it in PowerDNS with a database and a web UI, no more files.” “Just upgrade BIND to 9.20 and script the serial.” The finance head asked whether any of this costs money.
The question: what should this team run for internal authoritative DNS and for resolution, how should Kubernetes and the public zone fit in, and what must change apart from the software?
The short version
- Separate the two roles first. An authoritative server answers for zones you own. A recursive resolver finds answers for anything, by asking other servers and caching what it learns. Mixing them in one process is how small setups start and how many problems begin.
- BIND 9 (ISC, MPL 2.0) does both roles in one program,
named. The current branch is BIND 9.20, an Extended Support Version, at 9.20.30 (21 October 2026), with end of life planned for the second quarter of 2028. ISC’s matrix lists 37 distinct 2026 CVE IDs fixed in 9.20 so far. - PowerDNS (GPL 2.0, now part of Open-Xchange) splits the roles into separate products. Authoritative Server 5.1 (5.1.0 on 3 June 2026, latest 5.1.5 on 21 October 2026) keeps zones in SQL, LMDB or BIND-style files behind a REST API. Recursor 5.4 (5.4.0 on 9 March 2026, latest 5.4.9 on 26 October 2026) is the resolver. dnsdist 2.1 is a DNS load balancer in front of either.
- CoreDNS (Apache 2.0, a CNCF graduated project) is a single Go binary built from plugins. It is the Kubernetes default, now at 1.15.0 (21 October 2026). It serves zones, acts as a secondary, forwards and caches, but is not a full recursive resolver.
- Knot DNS, Knot Resolver and Unbound are strong single-role options.
If you remember one thing: the real problem in most teams is not the DNS server but the way records are changed. Move record changes into Git with review, let a tool push them through an API or a generated zone file, and keep authoritative and recursive roles apart. The choice of server comes after that.
Where things stand on 28 October 2026
BIND 9. ISC’s download page lists 9.20.30 as the current stable release and an Extended Support Version, with end of life in the second quarter of 2028. The 9.18 line (last release 9.18.50, June 2026) is now end of life, and 9.21 is the development branch. BIND 9.20.0 came out on 23 July 2024. Upgraders should know three things: the auto-dnssec option is removed in favour of dnssec-policy; several older DNSSEC options are obsolete; and the old red-black tree database was replaced by a QP-trie, which ISC says uses roughly 15 percent more memory for large zones in the current implementation. ISC’s matrix also shows two 2026 releases that were withdrawn after publication (9.20.25 and 9.20.28), so read the announcement, not only the package version.
PowerDNS. The Authoritative Server end of life page lists 5.1 (released 3 June 2026) as the supported train, 5.0 (22 August 2025) as critical fixes only until around March 2027, and 4.9 as ending around September 2026. Notable 5.1 changes: Lua records immutable by default, a CORS setting for the web server, structured logging, nested catalog zones, finer-grained record set changes through the API, and removal of the option to pass the API key as a URL query argument. For the Recursor, 5.4 is supported, 5.3 gets critical fixes for one year after 5.4 was released, and 5.2 and older are end of life. For dnsdist, 2.1 is current (2.1.3 on 12 October 2026), 2.0 gets critical fixes until 2 July 2027, and 1.9 reached end of life on 21 July 2026.
CoreDNS. CoreDNS 1.15.0 (21 October 2026, built with Go 1.27.3) adds DNS-over-QUIC upstreams in the forward plugin, optional JSON query logging, authenticated RFC 2136 dynamic updates and PROXY protocol v2 metadata, with many cache and forwarding fixes. One small change: the cache plugin no longer sets the authoritative answer (AA) flag on cached answers. The 1.14.x releases in 2026 added secondary zone management and serving catalog member zones in the secondary plugin.
Root zone key rollover. IANA’s trust anchor page shows the new root key signing key, KSK-2024 with key tag 38696, published in the root zone on 11 January 2025 and signing since 11 October 2026. The old key, KSK-2017 (key tag 20326), is due to be revoked on 11 January 2027 and removed on 22 March 2027. ICANN reported on 15 October 2026 that the rollover completed as planned and that it was assessing reports of issues on a limited number of systems. A validating resolver without KSK-2024 as a trust anchor would have started failing on 11 October. BIND 9.20 now warns when configured root trust anchors include an older key but not the new one.
Knot and Unbound. Knot DNS 3.6.2 came out on 21 October 2026, Knot Resolver 6.5.1 on 22 October 2026 with security fixes, and Unbound 1.26.2 on 21 October 2026.
Private names. On 29 July 2024 the ICANN Board reserved .internal permanently for private use. For a new internal zone, a name under .internal or a subdomain of a domain you own (such as int.yourcompany.in) is far safer than an invented top-level name such as .corp. Avoid .local, which multicast DNS uses on many systems.
Security in 2026: a busy year for DNS software
The advisories are worth reading together, because they change how you plan upgrades.
- BIND 9. ISC’s vulnerability matrix lists 37 distinct 2026 CVE IDs fixed in the 9.20 branch so far. 9.20.30 (21 October) fixed four, including CVE-2026-19630 (amplified resource exhaustion in inbound message processing) and CVE-2026-94300 (memory corruption from concurrent GSS-TSIG messages). 9.20.29 (16 September) fixed fourteen, including CVE-2026-19033, where unauthenticated IXFR changes could reach the live zone before TSIG verification. 9.20.26 (22 July) fixed nine, including a cache poisoning issue (CVE-2026-11721) and a DNSSEC validation bypass (CVE-2026-13321). Many affect only resolvers or features such as RPZ, DNS64, DNS-over-HTTPS or GSS-TSIG.
- PowerDNS. The 2026 advisories include 2026-07 (input validation in the internal web server), 2026-11 (CVE-2026-52682, 6 August, crafted packets raising memory and CPU use in the Authoritative Server, Recursor and dnsdist), 2026-12 (Recursor, fixed in 5.4.8) and 2026-13 (CVE-2026-73206, 21 October, rated High, a denial of service through crafted compression pointers, fixed in Authoritative 4.9.18, 5.0.8 and 5.1.5 and described as multi-vendor).
- CoreDNS. The 2026 GitHub advisories include an ACL bypass and a loop plugin denial of service (March), two TSIG authentication bypasses on encrypted and gRPC transports (April), a subzone transfer ACL bypass (CVE-2026-33489, April), a PROXY protocol crash (July), memory exhaustion in custom transports (September) and a bypass of UPDATE rejection on DoH, DoQ and gRPC (September). Releases also carry Go toolchain fixes.
The pattern is clear: features that look like extras (encrypted transports, TSIG on new transports, RPZ, DNS64, PROXY protocol, built-in web servers) are where many 2026 bugs sat. Turn on only what you use, and patch DNS servers within days, not quarters.
First question: why do you want to change?
Before comparing servers, write down why the discussion started. In the Ranchi case, neither trigger was really about BIND.
- The stale database record came from a manual edit without a serial bump. Any server that reads zone files and transfers them by serial would behave the same way. The fix is a process where people do not edit zone files at all: records live in a repository, a tool generates the zone or calls an API, and the serial is handled by the tool.
- The root key question is about the resolver, not the authoritative server. It needs a resolver that is supported, has a known trust anchor configuration and is monitored.
- BIND 9.16 is unsupported, which is a real risk on a server that answers queries from every machine in the company. That is an upgrade problem first.
So the first decision is not CoreDNS versus PowerDNS. It is: which servers are authoritative for which zones, which servers resolve for which clients, and how records are changed.
Authoritative and recursive: two different jobs
An authoritative server holds zones. For corp.internal, it knows every record and answers with the AA flag set. If someone asks it about a name it does not hold, it should refuse or refer, not go looking.
A recursive resolver answers questions from clients about any name. It starts from the root, follows referrals to the right authoritative servers, validates DNSSEC signatures if configured, caches answers for their TTL and returns them. It handles untrusted data from the internet, so cache poisoning and validation bugs, like several of the 2026 CVEs above, live here.
A forwarder is a resolver that does not walk the tree itself but sends queries to another resolver. CoreDNS in Kubernetes mostly works this way: it answers cluster names itself and forwards everything else to the node’s resolver or to an upstream you choose.
When one BIND process does both jobs, a bug in the resolver path can take down the authoritative service, a cache problem can hide a zone change, and access rules for “who may resolve” get mixed with “who may transfer zones”. Splitting the roles, even on the same small VMs, makes each part simpler.
What each server is
BIND 9
BIND was written by graduate students at the University of California, Berkeley, in the 1980s, under a DARPA grant. ISC and its predecessor have maintained it since version 4.9.3, and BIND 9, a near complete rewrite, came out in September 2000. ISC is a non-profit that also runs F-Root and makes Kea DHCP. The source is under MPL 2.0, and ISC sells support.
One process, named, can be authoritative, recursive or both. Zones are usually text files, and BIND also supports dynamic updates with TSIG keys, inline DNSSEC signing, catalog zones, views (different answers for different clients), response policy zones (RPZ), and DNS-over-TLS and DNS-over-HTTPS listeners. rndc controls a running server, and a statistics channel gives XML or JSON. Stable branches have even minor numbers (9.18, 9.20), development branches odd ones (9.21), and some stable branches are marked Extended Support Versions.
PowerDNS Authoritative, Recursor and dnsdist
PowerDNS development started in 1999, and Bert Hubert released it as open source under the GPL in November 2002. PowerDNS merged with Open-Xchange in 2015. It ships three separate products.
The Authoritative Server serves zones from backends: generic SQL (MySQL, PostgreSQL, SQLite), LMDB, BIND-style zone files, a remote backend, Lua records and others. Records are rows, not lines in a file. A built-in web server exposes a REST API for zones and records and a Prometheus-format /metrics endpoint. pdnsutil manages zones and DNSSEC keys. With database backends, PowerDNS signs answers as it sends them, using keys stored in the database. It can be primary or secondary with AXFR and IXFR, or you can replicate the database instead.
The Recursor is a separate validating resolver with Lua scripting, RPZ, a packet cache and its own API and metrics. Recent versions use YAML settings, with a conversion guide in the documentation. dnsdist is a DNS-aware load balancer and filter that sits in front of either, with rate limiting and DNS-over-TLS and DNS-over-HTTPS termination. A small internal setup rarely needs it.
CoreDNS
CoreDNS was created in March 2016 by Miek Gieben, then at Google. It joined the CNCF in 2017 and graduated on 24 January 2019. Kubernetes 1.11 (June 2018) made it generally available for cluster DNS and the kubeadm default, and Kubernetes 1.13 (December 2018) made it the default DNS server, replacing kube-dns. It is under Apache 2.0.
CoreDNS is one Go binary configured with a Corefile. Each server block names a zone, a port and a chain of plugins: kubernetes answers for Services and Pods, file and auto serve zone files, secondary pulls zones, transfer allows outgoing transfers, forward and cache handle everything else, prometheus exposes metrics, acl limits who may query, and dnssec signs answers on the fly with keys you provide. You can build your own binary with external plugins.
What CoreDNS is not: a full recursive resolver that walks the tree from the root and validates DNSSEC. In practice it forwards to one. It is also not built as a database-backed authoritative platform with a record API.
Knot DNS, Knot Resolver and Unbound
- Knot DNS from CZ.NIC, the Czech registry, is authoritative only, under GPL 3 or later. It supports IXFR, dynamic updates, response rate limiting and automatic DNSSEC signing, and its authors design it for root and TLD use.
- Knot Resolver from CZ.NIC is a caching resolver with a small core and optional modules.
- Unbound from NLnet Labs is a validating, caching resolver under the BSD licence. It is simple to run, can serve a few local records, and is not meant to be your authoritative server.
Side by side
Licence, ownership and support
- BIND 9: MPL 2.0, ISC (non-profit), paid support and early vulnerability notification available, published end of life dates.
- PowerDNS: GPL 2.0, PowerDNS (part of Open-Xchange), paid support including for end of life versions. The aim is a major release about every six months, with older trains getting critical fixes for about a year after the next one.
- CoreDNS: Apache 2.0, CNCF project with community maintainers. No long-term support branch; Kubernetes distributions and cloud providers support the CoreDNS they ship.
- Knot DNS and Knot Resolver: GPL, CZ.NIC, with commercial support. Unbound: BSD, NLnet Labs (non-profit).
None needs a licence fee. The cost is people’s time and, if you want it, a support contract.
Roles
- BIND 9: both roles in one process; you can and should run separate instances.
- PowerDNS: a separate product for each role, plus dnsdist in front.
- CoreDNS: authoritative for zones it holds, and a forwarding cache for the rest.
- Knot DNS: authoritative only. Knot Resolver and Unbound: resolvers only.
Where zone data lives
This decides how people change records, and it matters most for the Ranchi team.
- Zone files (BIND, Knot DNS, CoreDNS, PowerDNS BIND backend): easy to keep in Git and review, easy to check with
named-checkzone. The risks are hand edits, forgotten serials and syntax slips, so generate or check them in CI. - SQL or LMDB (PowerDNS): records are rows, changed through the API or
pdnsutil. Easy to connect to tools and a UI; hard to review unless every change comes from code. The database is one more thing to back up and patch. - Kubernetes API (CoreDNS
kubernetesplugin): records come from Services and EndpointSlices. Right for cluster names, wrong for anything else. - Dynamic updates (RFC 2136 in BIND, Knot DNS, PowerDNS and CoreDNS 1.15.0): tools send signed updates. Good for DHCP and ACME DNS-01; the file on disk then becomes a base plus a journal, and nobody should edit it by hand.
Zone transfers, NOTIFY and TSIG
Secondaries copy zones with AXFR (the whole zone) or IXFR (only the changes since a serial). The primary sends NOTIFY when a zone changes; the secondary checks the SOA serial and transfers only if it has increased. If the serial does not increase, nothing moves, which is exactly the Ranchi incident.
- Protect transfers and NOTIFY with TSIG keys and IP restrictions. Never allow AXFR from anywhere; a full zone is a map of your network.
- BIND and Knot DNS have mature AXFR and IXFR in both directions. BIND’s CVE-2026-19033 fix shows this path still deserves attention.
- PowerDNS supports primary and secondary roles and catalog zones; with SQL many teams replicate the database instead, and then database security replaces TSIG.
- CoreDNS uses
transferfor outgoing transfers andsecondaryto pull. In our drill atransfer to 127.0.0.1rule also made CoreDNS send NOTIFY to port 53 on that address. It also fixed a subzone transfer ACL bypass (CVE-2026-33489) this year. - Catalog zones (RFC 9432) publish the list of zones as a zone, so secondaries add and remove zones by themselves. BIND, PowerDNS, Knot DNS and CoreDNS all have some support; check which role (producer or consumer) each supports before relying on it.
DNSSEC signing and key rollover
For zones under .internal, signing is usually pointless, because there is no parent to hold a DS record. For public zones, sign if you can operate it. Validation on your resolvers is worth having always.
- BIND 9.20 uses
dnssec-policy: you declare algorithms and key lifetimes, andnamedcreates keys, signs and rolls them. KSK rolls still need the parent DS to change; BIND can publish CDS and CDNSKEY records for that. 9.20 added key stores with PKCS#11 for HSMs and multi-signer support (RFC 8901). Anauto-dnssecconfiguration will not load on 9.20. - PowerDNS signs on the fly with keys in the database.
pdnsutilcreates and activates keys; rollovers are documented steps you run or automate. - Knot DNS manages keys and signing automatically, including KSK rollover with CDS or CDNSKEY.
- CoreDNS
dnssecsigns answers with keys you supply and does not manage key life cycles. It is not our first pick for a signed public zone.
On resolvers, the 11 October 2026 root rollover is the real test. A resolver using RFC 5011 automatic trust anchor updates that had run long enough would have learned KSK-2024 on its own. One with a fixed trust anchor in an old package or container image, or one that cannot write its trust anchor state to disk, might not. Check, do not assume.
APIs and DNS-as-code
- PowerDNS Authoritative has the most complete built-in record API, and octoDNS, DNSControl, external-dns and cert-manager DNS-01 webhooks can use it.
- BIND is changed through files plus
rndc reload, or RFC 2136 updates with TSIG. - CoreDNS has no record API; you change files, Kubernetes objects, etcd or a cloud backend, or since 1.15.0 send authenticated RFC 2136 updates.
- octoDNS (MIT) keeps zones as YAML in Git with a plan step before applying; DNSControl keeps them in a JavaScript-like file with a preview step. Both can drive two providers at once, which helps in a migration. external-dns (Apache 2.0, v0.24.0 on 23 October 2026) creates records from Kubernetes Services and Ingresses.
Performance
We ran no benchmark and quote no numbers. Knot DNS and Knot Resolver publish benchmark pages, and other projects have published comparisons; treat each as the vendor’s own run on its own hardware and query mix.
- For a few hundred records and a few hundred clients, every server here is far faster than you need. Choose for operations.
- For resolvers, cache hit rate, upstream latency and timeouts matter more than queries per second.
- In Kubernetes, the default
ndots:5search path turns one external lookup into several queries. NodeLocal DNSCache, theautopathplugin or fully qualified names help more than changing software. - If you need numbers, run DNS-OARC’s
dnsperfwith your own query mix.
Operations and monitoring
- BIND:
rndc,named-checkconf(9.20 adds-kto check DNSSEC keys against the policy),named-checkzone, and the statistics channel for exporters. - PowerDNS: web server statistics and
/metrics,pdns_controlandrec_control, structured logs in 5.1. Protect the web server and API with a key and an allow list; advisory 2026-07 was about that web server. - CoreDNS:
prometheus,health,ready,reload,log,errors, and JSON query logs from 1.15.0. - All: probe every server from outside with real queries; the blackbox exporter and other uptime tools can do this. And alert when the SOA serial differs between primary and secondaries for more than a few minutes. That one check would have caught the Ranchi incident in minutes.
Fit with Kubernetes
- Keep CoreDNS as cluster DNS; replacing it gains little.
- Add a
forwardblock socorp.internalgoes to your internal resolvers, and keep it in Git. - Give external-dns its own subzone, such as
k8s.corp.internal, so it cannot overwrite other records. - Do not make the cluster CoreDNS the company’s authoritative server. If the cluster has a bad day, the office should still resolve names.
What actually happens during a lookup and a migration
When a laptop in the Ranchi office looks up erp.corp.internal:
- The laptop sends the query to its configured resolver.
- The resolver checks its cache and answers at once if the TTL has not expired.
- Otherwise, in today’s setup
namedanswers from its own copy of the zone. In a split design, the resolver has a forward or stub zone forcorp.internal, asks the authoritative servers, caches the answer and returns it. - For a public name, the resolver walks from the root, validates DNSSEC up to the root trust anchor (now KSK-2024), caches and answers.
When a record changes, old answers can sit in the resolver cache, a forwarder cache such as CoreDNS in the cluster, and the client. TTLs decide for how long. Lower the TTL a day before a planned move, change the record, check every authoritative server, and raise the TTL later.
A migration moves in stages: new authoritative servers load the same zones, you compare answers for every record, resolvers switch to the new authoritative servers, clients move to the new resolvers through DHCP and server settings, and only then do the old servers go. At each stage the old path still works, so rollback is a configuration change.
A worked plan for the Ranchi team
Step 1: Inventory zones, clients and resolvers
List every forward and reverse zone with its owner and authoritative servers, and every client group with the resolver it uses (office DHCP, rack servers, VPN users, Kubernetes nodes, CoreDNS forward rules). Export the zones with an AXFR from an allowed address into a new Git repository. That alone gives the team its first history.
Step 2: Stop hand edits now
Before any new software, set a rule: nobody edits zone files on the server. Changes go into the repository and are reviewed, and a small CI job runs named-checkzone, sets a date-based serial such as 2026102801, copies the file to the primary and runs rndc reload. This bridge closes the incident’s root cause within a week.
Step 3: Split the roles
Build two resolver VMs, one in the Ranchi rack and one in the cloud region, running Unbound or PowerDNS Recursor 5.4. Add a forward or stub zone for corp.internal and the reverse zones pointing at the authoritative servers, restrict queries to company networks, and confirm the root trust anchor includes key tag 38696 and that the resolver can write its trust anchor state to disk. Pick the Recursor if the authoritative side will be PowerDNS, so the team learns one vendor’s tools; pick Unbound if BIND stays, because it is small and easy to reason about.
Step 4: Choose the authoritative server and where records live
- Path A: PowerDNS Authoritative 5.1 with PostgreSQL or LMDB, records managed only through octoDNS or DNSControl and pushed through the API, a hidden primary and two secondaries fed by AXFR and IXFR with TSIG (or database replication). The API suits cert-manager DNS-01 and self-service. The cost is a database.
- Path B: BIND 9.20 with zone files generated from the same Git repository, a hidden primary and two secondaries with TSIG, no database, and
dnssec-policyready if a public zone is signed later.
With 600 records, no signing need today and one engineer who knows BIND well, Path B is the smaller change. Path A wins if many teams will create records through an API or UI. CoreDNS is not the right primary for company-wide zones here.
Step 5: Run old and new side by side
Load the zones into the new servers. A script queries every name and type from the repository against the old primary, the old secondary and each new server, and reports differences. Run it daily until clean, then point the new resolvers at the new authoritative servers.
Step 6: Move clients in waves
Change the DHCP option for one office first, then rack servers, then VPN users, then the CoreDNS forward rule. Keep the old servers running for a week after the last wave, and watch SERVFAIL and NXDOMAIN rates.
Step 7: Bring the public zone into code
Export the public zone from the registrar, add it to the repository with octoDNS or DNSControl, and run preview until it shows no differences. Then every change goes through review. Replace the shared login with personal accounts using two-factor authentication, plus one break-glass account.
Step 8: Monitor and retire
Add probes for every server, a serial mismatch alert, resolver SERVFAIL rate and DNSSEC validation failures. Subscribe to ISC, PowerDNS, NLnet Labs and CoreDNS security announcements, and apply DNS security releases within a week. Then retire the BIND 9.16 servers.
When CoreDNS is the better choice
- You need DNS for a Kubernetes cluster. CoreDNS is already there.
- You need a small, static internal zone served close to applications, for example a handful of service names in an edge site, and you like one binary with a short configuration.
- You want custom behaviour (rewrites, special answers, integration with etcd or a cloud DNS service) and are happy to write or build plugins in Go.
When PowerDNS is the better choice
- Many people or systems need to create records through an API, and you want a database as the source of truth with a UI or self-service portal on top.
- You host many zones, for example one per customer, and want to add and remove them without editing configuration files.
- You want dynamic answers with Lua records, such as health-checked records, and can live with the extra complexity.
- You want separate, well-documented products for authoritative, resolver and load balancing, from one vendor with a support option.
When BIND 9 or Knot is the better choice
- You want zone files in Git as the source of truth, with no database.
- You need automatic DNSSEC signing and key management on a public zone: BIND 9.20 with
dnssec-policy, or Knot DNS. - You need views, RPZ or other mature features that BIND has had for years.
- Your team already knows BIND, and the problem is an old version, not the software.
When not to change at all
If your DNS runs on a supported version, records are already changed through code with review, primaries and secondaries agree, resolvers validate with the right trust anchors and you are patching within days, there is no good reason to switch software in 2026. Spend the time on monitoring and on the process for changes. Changing DNS software is a risk to every service at once, and it should solve a problem you can name.
A short history, so the choices make sense
- 1980s: BIND is written at UC Berkeley; ISC later takes over its upkeep.
- May 1997 and September 2000: BIND 8, then BIND 9, a near complete rewrite.
- 1999 and 2002: PowerDNS development starts; it becomes open source under the GPL in November 2002.
- July 2010: the first root KSK (KSK-2010) starts signing the DNSSEC-signed root zone.
- 2015: PowerDNS merges with Open-Xchange.
- 2016 to 2019: CoreDNS is created (March 2016), becomes the Kubernetes default in 1.13 (December 2018) and graduates in the CNCF (January 2019).
- 11 October 2018: the first root KSK rollover, to KSK-2017.
- July 2024: BIND 9.20.0 is released, and ICANN reserves
.internal. - 2025: KSK-2024 published in the root zone (January); PowerDNS Authoritative 5.0 (August).
- 2026: PowerDNS Recursor 5.4 (March) and Authoritative 5.1 (June); BIND 9.18 reaches end of life; the root rolls to KSK-2024 on 11 October; CoreDNS 1.15.0, BIND 9.20.30, PowerDNS Authoritative 5.1.5, Knot DNS 3.6.2 and Unbound 1.26.2 arrive in the same October week, several with security fixes.
Operational costs to plan for
- Two of everything. At least two authoritative servers and two resolvers, in different failure domains. DNS outages are company outages.
- Patching time. In 2026 BIND, PowerDNS and CoreDNS all had several security releases. Plan for a DNS patch window every month and an emergency one when needed.
- A database, if you choose one. PowerDNS with SQL needs backups, upgrades and monitoring of the database as well.
- Key management, if you sign. DNSSEC keys need safe storage, documented rollover steps and a parent DS update process with your registrar.
- Change tooling. octoDNS or DNSControl, a CI job and code review. This is small but must be owned.
- Monitoring. Probes, serial checks, resolver error rates and query logs with a retention rule, because query logs show what every machine looks up and are sensitive.
- Learning time. Everyone on call should be able to read a zone, run
dig, read a resolver log and flush a cache. Practise once a quarter.
A decision guide
- Kubernetes cluster DNS: CoreDNS, with forward rules for internal zones.
- Small internal zones, files in Git, team knows BIND: BIND 9.20 authoritative, plus Unbound or PowerDNS Recursor as resolvers.
- Many zones or many writers, API and UI wanted: PowerDNS Authoritative 5.1 with a database, plus PowerDNS Recursor 5.4, and dnsdist only if you need load balancing or filtering.
- Public zone with automatic DNSSEC: BIND 9.20 with
dnssec-policy, or Knot DNS; or a managed DNS provider driven by octoDNS or DNSControl. - Records that follow Kubernetes objects: external-dns writing to a dedicated subzone.
- A working, supported setup with records in code: stay, and improve monitoring.
Checklist before you add another DNS record by hand
- Every zone has an owner, a list of authoritative servers and a source of truth in Git.
- Nobody edits zone files or records on a server or in a console directly.
- Serial numbers are set by a tool, never by a person.
- Authoritative and recursive roles are separate, even if they share hardware.
- Zone transfers and NOTIFY are limited by IP address and TSIG; AXFR is never open to the world.
- Resolvers validate DNSSEC and have KSK-2024 (key tag 38696) as a trust anchor.
- Internal zones use a name you own or a name under
.internal, not an invented top-level name. - Every DNS server runs a supported branch, and security releases are applied within a week.
- Probes check every server, and an alert fires if serials differ between servers.
- TTLs are lowered before planned changes and raised again afterwards.
- The CoreDNS configuration in each cluster is in Git, including forward rules added during incidents.
- The registrar and DNS provider accounts use personal logins with two-factor authentication.
Common mistakes
- Forgetting the serial. Secondaries do not transfer a zone whose serial has not increased. Let a tool set it.
- One server doing everything. A resolver bug or cache problem then hits your authoritative zones too.
- Open zone transfers. A full AXFR shows every internal name and address to anyone who asks.
- Assuming trust anchors update themselves. Old images and read-only containers may never learn a new root key.
- Using CoreDNS in the cluster as the company DNS. When the cluster fails, the office cannot resolve names.
- Turning on every feature. DoH, DoQ, PROXY protocol, RPZ and GSS-TSIG are useful, but they are where many 2026 advisories sat. Enable only what you use.
- Long TTLs during a migration. A one-day TTL means a one-day rollback.
- Leaving the PowerDNS API or web server reachable without an allow list. It can change every record.
- Upgrading BIND to 9.20 without reading the removed options.
auto-dnssecconfigurations will not load.
A small hands-on drill
We ran a small local drill on 28 October 2026, between about 2:22 AM and 2:24 AM IST, on a Linux x86_64 test machine, as a normal user, in a throwaway folder. We downloaded the official CoreDNS 1.15.0 Linux amd64 archive and its .sha256 file from the GitHub release page; sha256sum -c reported OK, and the binary reported CoreDNS-1.15.0 built with go1.27.3. dig was not installed, so we queried with the Python dnspython library (2.9.0) in a virtual environment in the drill folder. Everything listened only on 127.0.0.1: port 15353 for DNS and 19153 for metrics. No system packages, system files or services were touched. We did not run BIND, PowerDNS, Knot or Unbound, and we did not measure performance.
The zone corp.internal had serial 2026102801, an NS record, A records for ns1, erp (10.20.0.15) and api (10.20.0.21), and www as a CNAME to api. The Corefile used file with a 5 second reload, transfer to 127.0.0.1, prometheus, log and errors.
What we saw:
- Normal lookup:
erp.corp.internal AgaveNOERROR, flagsQR AA RD,10.20.0.15. AA set and RA not set, as an authoritative-only server should answer. - CNAME:
wwwreturned the CNAME and theArecord forapitogether. - Missing name:
nope.corp.internalgaveNXDOMAINwith the SOA in the authority section. - Outside the zone:
example.com AgaveREFUSED, since noforwardwas configured. - Zone transfer: an AXFR returned
@,api,erp,ns1andwww, and the log saidOutgoing transfer of 7 records of zone "corp.internal." to 127.0.0.1 for 2026102801 SOA serial. - Edit without serial bump: we changed
erpto 10.20.0.99, left the serial alone and waited 8 seconds. The answer was still10.20.0.15. This is the Ranchi incident in miniature. - Edit with serial bump: after setting the serial to
2026102802and waiting 8 seconds, the answer became10.20.0.99, and the log saidSuccessfully reloaded zone "corp.internal." in "db.corp.internal" with 2026102802 SOA serial. - A surprise NOTIFY: the log then warned that a NOTIFY to
127.0.0.1:53was refused. Thetransfer torule also sends NOTIFY to that address on port 53, where nothing listened in our drill. - Metrics:
coredns_dns_requests_totalshowed 1 AXFR, 9Aqueries for the zone and 3 underzone="dropped";coredns_dns_responses_totalshowed 3REFUSED;coredns_reload_failed_totalwas 0.
We then stopped CoreDNS and checked that no process was left running.
This is a tiny drill, not a test at scale. It shows three things the post argues: authoritative and recursive behaviour are visible in the flags, the serial decides whether a change is seen, and metrics reveal refused and unexpected queries without reading logs.
Unlearn, re-learn
Unlearn the idea that DNS is a set-and-forget service, and the habit of logging in to a server to add one record. Unlearn, too, the idea that one DNS process should resolve everything and own every zone. Re-learn DNS as two small systems with different jobs: authoritative servers that publish your zones from a reviewed source of truth, and resolvers that fetch, validate and cache everything else. Practise it by exporting your zones into Git this week, checking your resolvers for key tag 38696 today, and running a serial mismatch alert before your next record change.
Sources
- BIND 9: ISC downloads, versions and end of life dates, BIND 9 security vulnerability matrix, BIND 9.20 release notes, CVE-2026-19033 advisory, CVE-2026-19630 advisory, ISC software support policy
- PowerDNS: Authoritative Server end of life statements, Authoritative 5.1 changelog, Authoritative security advisories, Advisory 2026-13, Advisory 2026-11, Recursor end of life statements, Recursor 5.4 changelog, dnsdist end of life, dnsdist changelog, PowerDNS repository
- CoreDNS: GitHub releases (1.15.0, 1.14.x), security advisories, plugin documentation, CNCF graduation announcement, Kubernetes 1.11 CoreDNS GA, Kubernetes 1.13 release announcement
- Root key rollover: IANA DNSSEC trust anchors and rollovers, ICANN root zone KSK rollover page, ICANN announcement, 15 October 2026
- Private names: ICANN Board resolution reserving .INTERNAL, 29 July 2024
- Knot and Unbound: Knot DNS, Knot Resolver, Unbound releases
- DNS-as-code: octoDNS, DNSControl, external-dns releases
- Drill: our own run, 28 October 2026, notes kept with the post
Releted Posts
Kubernetes pod networking in 2026: revisit Cilium, Calico and Flannel before you pick another CNI plugin
Picture a software company in Mangaluru that builds billing and stock software for chemists (an invented example, not a real client).
Read moreTLS certificate automation in 2026: revisit cert-manager, Certbot and step-ca before the next certificate expires on you
Think of a bicycle and auto parts manufacturer in Ludhiana that sells through about 400 dealers across Punjab, Haryana, Rajasthan and the hill states (an invented example, not a real client).
Read moreVulnerability scanners in 2026: revisit Trivy, Grype and OSV-Scanner before you trust another green scan
Picture a small software company in Bhubaneswar that builds claims and pre-authorisation software for hospitals that deal with health insurance TPAs (an invented example, not a real client).
Read more