Open-source project
NLnetLabs/unbound avatar
NLnetLabs/unbound

Unbound: a validating recursive resolver you run yourself

Unbound is a validating, recursive, and caching DNS resolver.

4,956 stars457 forksCBSD-3-Clause

At a glance

What is it?
Unbound is NLnet Labs' BSD-3-Clause C resolver. It answers from cache, validates DNSSEC itself, and is built from source with ./configure && make && make install. Here is what it does, how to start it, and when a forwarder is the better choice.
Who is it for?
Adopt Unbound if you want a resolver you control end to end: recursive from the root, DNSSEC-validating in your own process, configured from a single unbound.conf and available in most distribution package sets. Do not adopt it if you only need to forward queries to an upstream resolver, or if you cannot own the operational work of a recursive service.
Can I use it commercially?
Yes. BSD-3-Clause 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 received new commits within the last day.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Unbound is for, and who ends up running it

Unbound is a validating, recursive, caching DNS resolver. The README states it plainly, and the three words map to three separate jobs. Recursive means it walks from the root servers down to the authoritative server for a name instead of asking someone else to do it. Validating means it checks DNSSEC signatures on the answers it receives. Caching means the second query for the same name is answered locally.

That combination is what separates it from a stub resolver on a laptop or a forwarder pointed at a public DNS service. If you run Unbound, the DNS traffic for your users leaves your network as queries to authoritative servers, not as one stream to a single upstream provider. For network operators, that is the point. For a single laptop, it is usually more machinery than the problem needs.

The audience the repository implies is infrastructure people: someone configuring a resolver for an office, an ISP, a hosting environment or a lab. The topics listed for the project are dns, dns-privacy, dnssec, recursor and resolver, which is a fair summary of the intent. It is not a DNS hosting control panel and it is not an authoritative server for your own zones. It resolves names for clients that ask it.

The recursion and validation path inside Unbound

The repository layout shows the architecture as directories rather than a single daemon file. The iterator/ directory holds the logic that walks the delegation chain. validator/ holds DNSSEC validation. services/ holds the cache and the mesh of outstanding queries. daemon/ holds the server process and its configuration handling. sldns/ carries the DNS parsing code. libunbound/ is the library form of the same resolver, so the daemon and the embeddable library share the core.

A query arrives, the cache is checked, and on a miss the iterator starts from the root and follows referrals. Answers that come back with DNSSEC records go through the validator before the client sees them. The cache stores what was validated, so the next client asking the same name gets the cached answer.

Two details in the README shape how this behaves under load. First, libevent support is optional and is chosen at configure time with --with-libevent, described as useful when using many outgoing ports, with 10000 given as the example. Second, without libevent the builtin alternative opens at most 256 ports at the same time, and the README calls it equally capable and a little faster. That is a real trade-off, not a footnote: the number of simultaneous outgoing ports bounds how many in-flight queries the resolver can have at once, so a busy resolver with the builtin port handling has a ceiling that a libevent build raises. The README does not give a query-per-second figure for either path.

Building Unbound from source and starting it

The README lists the build dependencies: a C toolchain, OpenSSL and its include files, and libexpat. Building from the repository source rather than a release tarball additionally needs flex and bison. The documented build sequence is short:

bash
./configure && make && make install

To build with libevent instead of the builtin port handling, the README gives the configure flag:

bash
./configure --with-libevent && make && make install

After installation, the configuration file is unbound.conf. The README points at doc/example.conf in the repository as an example configuration file with minimal documentation, and states that all options are described in the unbound.conf(5) man page, which is installed with the software and also published on the documentation site. The example file is the honest starting point: copy it, then read the man page for the options you change. The README does not reproduce a full configuration, so anything beyond the file location and the man page reference would be invention.

There is a second, larger surface in the repository that the README does not walk through. The top-level entries include pythonmod/, dynlibmod/, cachedb/, dnstap/, dns64/, dnscrypt/, edns-subnet/, ipsecmod/, ipset/ and respip/. Those are optional modules and features with their own configuration, and the README does not describe them. If you plan to use any of them, the man page and the documentation site are where the detail lives, not the README.

Where Unbound is the wrong tool

Unbound is a recursive resolver. If your actual need is to forward queries to an upstream resolver, or to serve your own zone authoritatively, Unbound is the wrong component and the configuration will fight you.

The operational cost is the larger limitation. A recursive resolver talks to authoritative servers across the internet, which means it can be used as a reflection and amplification source if it is left open to the world. The repository carries a SECURITY.md at the top level, which indicates the project treats security reports as a defined process, but the README itself says nothing about access control, rate limiting or which networks should be allowed to query the resolver. Those settings exist in unbound.conf according to the man page reference, but a reader who only reads the README will not learn from it that exposure is a decision they have to make.

There is also a scaling boundary that the README states directly. Without libevent, at most 256 outgoing ports are open at the same time. On a small network that is invisible. On a resolver serving many clients with cold caches, it is a constraint you should size against before deployment, not after. And the build itself is a C project with OpenSSL and libexpat as dependencies, which means you inherit their update cadence alongside Unbound's.

Unbound compared with dnsmasq and BIND

The closest comparison for most small deployments is dnsmasq, which is commonly used as a forwarder and local cache. The difference is in the default posture. dnsmasq forwards to configured upstream servers and caches the answers. Unbound resolves recursively from the root and validates DNSSEC itself. If your goal is to stop sending every query to one upstream provider, a forwarder does not achieve it; you need recursion, which is what Unbound does. If your goal is only to speed up repeated lookups on a home network, dnsmasq does that with less configuration and less exposure.

Against BIND, the split is scope and history. BIND is a full name server suite that can be authoritative for zones and recursive for clients, with a large configuration language. Unbound is deliberately narrower: a resolver, with the repository organized around the iterator, validator and cache rather than around zone files. If you need to host zones, Unbound is not the tool. If you need only resolution and validation, the narrower surface is easier to reason about.

One more comparison is worth naming because it appears in the repository: libunbound/. Unbound exists both as a daemon and as a library, so an application that wants to resolve names with validation can link against the same core rather than shelling out to a resolver. The README does not document that interface; the library directory and the documentation site are where it would be described.

Maintenance, releases and the licence

The repository is not archived, and the last push was on 2026-09-22. Recent releases are release-1.26.1 on 2026-09-16, release-1.26.0 on 2026-08-04, and release-1.25.2 on 2026-07-22. The cadence visible in those three dates is roughly one release per month to two months, with patch releases between feature releases. That matters for planning: a resolver is exposed to the internet's DNS, so being able to take a patch release on a short cycle is part of the operating model. The README does not document an upgrade procedure, so how you move from one release to the next is something to establish from the documentation site and your packaging, not from the README.

The licence is BSD-3-Clause. For most adopters that is a permissive licence with few obligations beyond retaining the copyright notice and licence text, and it does not impose copyleft on the rest of your stack. This is not legal advice; if you redistribute Unbound inside a product, read the LICENSE file in the repository and get your own answer.

On upgrade cost, the honest answer from the README and the release list is that the cost sits in configuration drift rather than in the build. The README points at doc/example.conf and the man page, and the man page is versioned with the release. Options can be added or changed between releases, and the release notes are the place that would say so. The README does not describe a compatibility policy for unbound.conf.

Editorial conclusion

Adopt Unbound if you want a resolver you control end to end: recursive from the root, DNSSEC-validating in your own process, configured from a single unbound.conf and available in most distribution package sets. Do not adopt it if you only need to forward queries to an upstream resolver, or if you cannot own the operational work of a recursive service. Before deploying, verify three things in the man page for your build: how many outgoing ports your configuration opens, whether the chroot and user settings match your filesystem, and what the release notes for release-1.26.1 changed relative to the version you are running.

Frequently asked questions

How do I install Unbound?

The README gives the source build as ./configure && make && make install, after installing a C toolchain, OpenSSL with its include files, and libexpat. Building from the repository source also needs flex and bison. The README notes Unbound is present in many distribution package sets via the packaging status badge, but it does not list package manager commands.

How do I use Unbound as a DNS resolver?

Unbound is a validating, recursive, caching resolver, so it answers queries by resolving them from the root and validating DNSSEC rather than forwarding to an upstream. Configuration lives in unbound.conf, with doc/example.conf in the repository as an example file and the unbound.conf(5) man page describing every option.

Can I install Unbound on a Raspberry Pi?

The README does not mention Raspberry Pi or any specific hardware. It states the build requirements, which are a C toolchain, OpenSSL with include files, and libexpat, plus flex and bison when building from the repository source. Whether a given board meets those requirements is not addressed in the README.

How do I install Unbound alongside Pi-hole?

The README does not mention Pi-hole or any integration with it. Unbound is configured through unbound.conf, described by the unbound.conf(5) man page, and the README gives no guidance on combining it with other DNS software.

What does the name Unbound mean for this resolver?

The project's README does not explain the origin of the name. It describes the software as a validating, recursive, caching DNS resolver, which is the only definition the README supports.

Official sources

  1. License: BSD-3-Clause
  2. NLnetLabs/unbound on GitHub
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/nlnetlabs-unbound.svg)](https://hysenlabs.com/projects/nlnetlabs-unbound)