CoreDNS: A Plugin-Chained DNS Server That Puts Configuration First
Project brief: CoreDNS is a DNS server that chains plugins. CoreDNS is a DNS server/forwarder, written in Go, that chains plugins.
At a glance
- What is it?
- CoreDNS is a Go-based DNS server and forwarder that chains plugins to handle zone files, Kubernetes, caching, and forwarding. Its Corefile configuration and plugin model make it flexible, but that flexibility comes with a learning curve and a build-time plugin constraint.
- Who is it for?
- Adopt CoreDNS if you need a DNS server that can serve zone files, act as a secondary, forward queries, cache responses, and integrate with Kubernetes or etcd, all from one binary. Do not adopt it if you need a DNS server with a fixed feature set and minimal configuration, because the plugin model requires you to understand which plugins to enable and how they interact.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 13, 2026, and from our analysis. They are not legal advice.
Star history
- coredns/coredns14,428 ★ · +205
| Repository | 2026-08-04 | 2026-11-13 |
|---|---|---|
| coredns/coredns | 14.2k | 14.4k |
205 Stars in the last 101 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
The Problem: DNS Servers That Are Too Rigid or Too Monolithic
Traditional DNS servers often bundle a fixed set of features. You get zone serving, forwarding, caching, and maybe DNSSEC, but adding a new behavior means patching the server or running a separate daemon. CoreDNS attacks that problem by making every function a plugin. The README states that each plugin performs a DNS function, and the core server simply chains them. This design suits operators who want to compose a DNS server from small, testable pieces. It is especially aimed at cloud-native environments, given its CNCF graduated status and the kubernetes plugin. If you need a DNS server that can serve zone data, forward queries, cache responses, and integrate with etcd or Kubernetes, CoreDNS is built for that.
The Mechanism: A Corefile That Chains Plugins Per Zone
CoreDNS reads a configuration file named Corefile. The file defines one or more server blocks, each with a zone and a list of plugins. For example, the README shows a minimal server block that forwards all queries to 8.8.8.8 and enables logging. The server block syntax is not JSON or YAML; it is a custom format that resembles a configuration language. Each plugin performs a DNS function, and the build includes plugins in the format of plugin.cfg. This chaining is the core architectural idea. The README explains that CoreDNS can listen on UDP/TCP, DoT, DoH, DoH3, DoQ, and gRPC, but those are server-level features. The plugin chain is where the actual DNS logic lives. For example, the file plugin serves zone data, the cache plugin stores responses, and the forward plugin sends unmatched queries upstream. The flexibility comes from choosing which plugins to include.
Getting It Running: From Source, Docker, or a Prebuilt Binary
The README gives two ways to build CoreDNS: from source and with Docker. To build from source, you need Go 1.26.0 or higher. The commands are straightforward: clone the repository, run make, and you get a coredns binary. The Docker method uses a golang:1.27 image and runs make gen and make inside the container. After building, you create a Corefile. The quick start example is a single server block that listens on port 53, forwards to 8.8.8.8, and enables log. You start the server with ./coredns -conf Corefile and test with dig @127.0.0.1 google.com. The README also notes that if you omit the port in the Corefile, it defaults to 53, but you can override with -dns.port. The Corefile supports import directives and environment variables, which helps with configuration reuse.
The Build-Time Plugin Constraint: A Hidden Cost
The README mentions that extra plugins may be enabled when building by setting the COREDNS_PLUGINS environment variable with a comma-separated list in the same format as plugin.cfg. That sentence reveals a significant limitation: plugins are not all loaded at runtime. The set of in-tree plugins is fixed at compile time. If you need a plugin that is not in the default build, you must rebuild the binary. This is a deliberate trade-off. It means that adding a plugin is not a configuration change; it is a build operation. For operators who are used to dropping a config file and reloading, this is a notable departure. Check plugin.cfg or the coredns.io/plugins page to know what you get. This is a real constraint that affects upgrade and maintenance workflows.
Limitations: AXFR-Only Zone Transfers and NSEC-Only DNSSEC
The README is explicit about two technical boundaries. First, when acting as a secondary server, CoreDNS retrieves zone data from primaries using AXFR only. That means incremental zone transfers (IXFR) are not supported. If your primary only offers IXFR, CoreDNS cannot act as a secondary for it. Second, when serving zone data from a file, DNSSEC support is limited to NSEC records, not NSEC3. The README says DNSSEC (NSEC only) is supported. That is a real limitation for zones that require NSEC3 for security reasons, such as those that want to prevent zone walking. These are not edge cases; they are core DNS features that many operators need. The README also mentions that CoreDNS can sign zone data on-the-fly with the dnssec plugin, but it does not specify whether that signing supports NSEC3. The absence of that detail suggests you should verify it before relying on it.
Alternatives: Comparing to a Traditional DNS Server
The most direct alternative is BIND, the long-standing open-source DNS server. BIND uses a named.conf file that is also text-based, but its architecture is monolithic. You enable features like recursion, zone serving, and DNSSEC within a single daemon, and you reload the configuration at runtime. CoreDNS, by contrast, compiles plugins into the binary and chains them per zone. The difference is not just in configuration syntax; it is in how you extend the server. With BIND, you configure existing features. With CoreDNS, you compose a server from plugins, and if a feature is missing, you either write a plugin or rebuild with an out-of-tree plugin. The README points to coredns.io/explugins for out-of-tree plugins, which confirms that the plugin ecosystem is the intended extension path. For operators who need a stable, well-known DNS server with a long history, BIND is a safer choice. For those who want a modular, Go-based server that can be embedded in cloud-native stacks, CoreDNS is the better fit.
Maintenance and Upgrade Cost: Go Version and Plugin Rebuilds
The README states that the Go version must be 1.26.0 or higher to compile. That is a high bar if your build environment is older. Upgrading CoreDNS means pulling a new release and rebuilding, especially if you use custom plugins. The recent releases, v1.15.0, v1.14.7, and v1.14.6, show an active release cadence. Check the release notes for breaking changes. The license is Apache-2.0, which is permissive and allows commercial use, but you should review the license text for specifics. The plugin model also means that if you rely on an out-of-tree plugin, you need to ensure it is compatible with the CoreDNS version you upgrade to. The README does not provide a compatibility matrix for plugins, so that verification is on you. This is a real maintenance cost that is easy to underestimate.
Editorial conclusion
Adopt CoreDNS if you need a DNS server that can serve zone files, act as a secondary, forward queries, cache responses, and integrate with Kubernetes or etcd, all from one binary. Do not adopt it if you need a DNS server with a fixed feature set and minimal configuration, because the plugin model requires you to understand which plugins to enable and how they interact. Before adopting, verify that the plugins you need are in-tree or that you are willing to build from source with the COREDNS_PLUGINS environment variable. Check the Go version requirement (1.26.0 or higher) and confirm that your zone transfer needs are met, since only AXFR is supported when acting as a secondary.
Frequently asked questions
What is CoreDNS and what is it used for?
CoreDNS is a DNS server and forwarder written in Go that chains plugins, where each plugin performs one DNS function, such as file or auto for zones, cache for caching, forward for proxying to a recursive resolver, and kubernetes or etcd as backends. It is a Cloud Native Computing Foundation graduated project and listens on UDP, TCP, TLS, HTTP/2, HTTP/3, QUIC and gRPC.
What does CoreDNS do in Kubernetes?
CoreDNS serves cluster DNS through the kubernetes plugin, using the Kubernetes API as a backend for zone data. Other backends and functions come from separate plugins in the same chain, such as cache, forward, prometheus and pprof.
How do I install CoreDNS on my own machine?
Clone the repository and run make with a Go setup, after checking that your golang version is 1.26.0 or higher. The README also gives a Docker alternative that mounts the source into a golang:1.27 container, and you can enable extra plugins at build time with the COREDNS_PLUGINS environment variable.
How do I start CoreDNS with a custom port when 53 is taken?
Either name a different port in the Corefile, for example .:1053 with the whoami plugin, or override it with the -dns.port flag, so coredns -dns.port 1053 runs the server on 1053. The default when no port is specified is 53.
Does -log-format=json also give me JSON query logs?
No. The flag changes operational log output for the whole process, including all server blocks, and persists across Corefile reloads, with records containing time, level and msg. Query logging still requires the log plugin, and debug output still requires debug.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/coredns-coredns)Star history chart for your README
[](https://hysenlabs.com/projects/coredns-coredns)Was this useful?