AVAHI vs systemd-resolved: can they coexist, and what breaks if both try to handle mDNS/DNS-SD?
Networking System Software

AVAHI vs systemd-resolved: can they coexist, and what breaks if both try to handle mDNS/DNS-SD?

11 min read

On a modern Linux system, AVAHI and systemd-resolved can absolutely coexist—but only if you draw a very clear line between which component owns mDNS/DNS-SD and how name resolution flows through nsswitch. If you let both try to “help” with multicast DNS at the same time, you don’t usually get more reliability; you get split-brain behavior, intermittent failures, and tools that only work sometimes.

Quick Answer: The safest overall choice for mDNS/DNS-SD on Linux desktops and small LANs is Avahi + nss-mdns. If your priority is centralizing all name resolution into systemd’s stack, systemd-resolved is often a stronger fit. For tightly controlled environments where you only need *.local resolution and no D-Bus browsing, consider systemd-resolved with Avahi limited to service publication only.


At-a-Glance Comparison

RankOptionBest ForPrimary StrengthWatch Out For
1Avahi + nss-mdnsFull mDNS/DNS-SD on Linux (Bonjour/Zeroconf-style)Mature, Linux-first mDNS/DNS-SD daemon with D-Bus API and XML service filesMust ensure systemd-resolved is not also trying to own mDNS on the same interfaces
2systemd-resolved (mDNS enabled)Centralized resolver stack with basic mDNSSingle resolver for unicast DNS + mDNS, integrated with systemdLacks Avahi’s D-Bus service-browse/publish model; fewer consumers expect this API
3Hybrid: systemd-resolved for DNS, Avahi for DNS-SDControlled setups that want Avahi’s DNS-SD but keep systemd-resolved for DNSKeeps unicast DNS with systemd-resolved while Avahi handles DNS-SD via D-BusEasy to misconfigure nsswitch and *.local handling; debugging split behavior can be painful

Comparison Criteria

We evaluated each setup based on three practical criteria:

  • mDNS/DNS-SD feature coverage:
    Whether the stack exposes not just *.local name resolution but also real DNS-SD browsing and service publication (printers, file shares, peer apps).

  • Integration surfaces & ecosystem compatibility:
    How well each option lines up with the way existing Linux software expects to talk to service discovery: D-Bus, XML under /etc/avahi/services, compatibility shims (Bonjour/Zeroconf), and nsswitch.

  • Operational clarity when coexisting:
    How easy it is to reason about “who owns what” when both Avahi and systemd-resolved are installed—especially around *.local resolution, interface binding, and debugging failures.


Detailed Breakdown

1. Avahi + nss-mdns (Best overall for full mDNS/DNS-SD on Linux)

Avahi + nss-mdns ranks as the top choice because it implements a full mDNS/DNS-SD stack with well-defined integration paths (D-Bus and /etc/avahi/services) and a clear story for *.local hostname resolution via nsswitch.

What it does well:

  • Full mDNS/DNS-SD with Bonjour/Zeroconf-style behavior:
    Avahi is explicitly “a system which facilitates service discovery on a local network via the mDNS/DNS-SD protocol suite.”
    Practically, that means:

    • Browsing services over D-Bus (e.g., find printers to print to, find files being shared).
    • Publishing services dynamically over D-Bus or statically via XML definitions in /etc/avahi/services.
    • Interoperating with Apple devices that speak Bonjour/Zeroconf.
  • Clear integration model for applications and distros:
    Avahi exposes:

    • A D-Bus API (primary API; required for most usage) for browsing/advertising services.
    • An XML-based static publisher via /etc/avahi/services so you can advertise services without writing a publisher.
    • Compatibility libraries (avahi-compat-libdns_sd, avahi-compat-howl) so software written for Bonjour or HOWL can work unchanged.

    For name resolution, the nss-mdns project “allows hostname lookup of *.local hostnames via mDNS in all system programs using nsswitch.” That’s what makes ping host.local and random CLI tools work.

Tradeoffs & Limitations:

  • You must keep systemd-resolved’s mDNS role in check:
    Avahi itself focuses on mDNS/DNS-SD; it doesn’t own unicast DNS. On modern systemd-based distributions, systemd-resolved is often the default stub resolver. If you also let systemd-resolved do mDNS on the same interfaces, you risk:
    • Competing responses on the mDNS multicast group.
    • Confusing nsswitch configuration where some tools hit nss-mdns → Avahi and others go via systemd-resolved.
    • Hard-to-reproduce “works in GUI app, fails in CLI” cases.

Decision Trigger:
Choose Avahi + nss-mdns if you want a complete mDNS/DNS-SD implementation and prioritize interoperability and established Linux integration (D-Bus, /etc/avahi/services, nsswitch). This is usually the right choice for desktops, laptops, and small LANs where “find printers and shared files” is the goal.


2. systemd-resolved (Best for unified resolver stack with basic mDNS)

systemd-resolved is the strongest fit when your priority is to centralize all name resolution—unicast DNS, DNS-over-TLS, and mDNS—under one daemon, rather than running a dedicated mDNS/DNS-SD system like Avahi.

What it does well:

  • Single resolver for regular DNS and mDNS:
    In a typical modern systemd setup, systemd-resolved:

    • Acts as a stub resolver on 127.0.0.53.
    • Handles upstream DNS, DNSSEC, DNS-over-TLS, and DNS configuration from systemd-networkd/NetworkManager.
    • Can be configured to do mDNS lookups for .local.

    This simplifies the mental model: all name resolution goes through a single path.

  • Tight integration with systemd tooling: You manage it with familiar systemd interfaces (systemctl, resolvectl). For admins already wiring everything through systemd, that’s operationally convenient.

Tradeoffs & Limitations:

  • Not a drop-in replacement for Avahi’s DNS-SD model:
    Avahi is centered around mDNS/DNS-SD as a system component with:

    • A D-Bus API for service browsing/registration.
    • Static service definitions via /etc/avahi/services.
    • Compatibility for Bonjour’s dns_sd.h API.

    Many desktop and LAN-aware applications are built to talk to Avahi (via D-Bus or Bonjour-compatibility), not directly to systemd-resolved. If you remove Avahi entirely:

    • Existing consumers expecting Avahi’s D-Bus API will lose service discovery.
    • You’ll have *.local resolution but not the rich DNS-SD browsing Avahi provides.

Decision Trigger:
Choose systemd-resolved with mDNS enabled and Avahi disabled if you value a single resolver stack over full DNS-SD capabilities, and your application set doesn’t depend on Avahi’s D-Bus or Bonjour compatibility. This tends to make sense on minimal servers or appliances that just need *.local name resolution.


3. Hybrid: systemd-resolved for DNS, Avahi for DNS-SD (Best for controlled, niche setups)

The hybrid setup stands out when you want systemd-resolved to keep handling unicast DNS, but still rely on Avahi’s D-Bus/DNS-SD model for service discovery. In practice, this is what many distributions ship: systemd-resolved as the resolver, Avahi as the mDNS/DNS-SD daemon, and nss-mdns bridging *.local into nsswitch.

What it does well:

  • Keeps unicast DNS and systemd features while preserving Avahi APIs:
    In this model:

    • systemd-resolved is still your stub resolver for “regular” DNS lookups.
    • Avahi runs as the mDNS/DNS-SD daemon (Bonjour/Zeroconf-compatible).
    • nss-mdns is used in /etc/nsswitch.conf to send *.local resolution to Avahi.

    Applications continue to use Avahi’s D-Bus or compat libraries for browsing and publishing services, while the OS still enjoys systemd-resolved’s DNS plumbing.

  • Closer to what many Linux ecosystems expect:
    This setup matches the reality that “Avahi is primarily targeted at Linux systems and ships by default in most distributions.” Many desktop stacks simply assume an Avahi daemon is present.

Tradeoffs & Limitations:

  • *Easy to misconfigure .local handling between the two daemons:
    The risk in a hybrid setup is letting systemd-resolved also decide it should speak mDNS on .local while nss-mdns sends the same traffic to Avahi. When that happens, things break in non-obvious ways:

    • Some tools resolve hostname.local via nss-mdns → Avahi.
    • Others go via glibc → systemd-resolved directly and get different behavior.
    • You may see intermittent or interface-dependent resolution failures.

    You have to be deliberate about:

    • How /etc/nsswitch.conf is ordered (where mdns/mdns_minimal/resolve appear).
    • Whether systemd-resolved’s mDNS support is enabled or disabled on specific links.
    • Avoiding two active mDNS responders trying to own the same hostname.

Decision Trigger:
Choose systemd-resolved for DNS + Avahi for DNS-SD if you want to keep systemd-resolved as the unicast DNS resolver but still rely on Avahi’s mature DNS-SD interfaces (D-Bus, /etc/avahi/services) and Bonjour compatibility. This is appropriate for distributions and environments that can enforce a sane nsswitch and link configuration.


Can Avahi and systemd-resolved coexist?

Yes, they can coexist. The key is making sure only one component is responsible for each function:

  • mDNS/DNS-SD advertising and browsing:
    Hand this to Avahi. That’s its whole job:

    • It runs a dedicated mDNS/DNS-SD stack.
    • It exposes a D-Bus API and /etc/avahi/services.
    • It provides Bonjour/Zeroconf interoperability.
  • Unicast DNS and general resolver duties:
    Let systemd-resolved own this (if your distro uses it):

    • Stub resolver on 127.0.0.53.
    • Upstream DNS, DNSSEC, DNS-over-TLS, etc.
  • *.local hostname resolution via system programs:
    Point this through nss-mdns → Avahi, not directly to systemd-resolved, if Avahi is your mDNS daemon. nss-mdns is explicitly “for hostname lookup of *.local hostnames via mDNS in all system programs using nsswitch.”

In that arrangement, Avahi and systemd-resolved live side by side, each handling their own scope without contention.


What breaks if both try to handle mDNS/DNS-SD?

If you leave both Avahi and systemd-resolved trying to own mDNS/DNS-SD on the same host and interfaces, you tend to see these classes of problems:

1. Split-brain *.local resolution

Symptoms:

  • ping host.local works from one terminal but fails from another tool.
  • GUI apps see printers and shares, but CLI tools don’t—or vice versa.
  • You get inconsistent responses for the same hostname depending on call path.

Why it happens:

  • Some lookups flow through glibc -> nsswitch -> nss-mdns -> Avahi.
  • Others flow through glibc -> systemd-resolved directly (e.g., via the stub resolver).
  • Both daemons are listening on the mDNS multicast group; they may respond differently or at different times.

Result: name resolution becomes non-deterministic from the user’s perspective.

2. mDNS hostname conflicts and flapping

If both daemons try to claim the same .local hostname:

  • You can see:
    • “Name in use” behavior or retries.
    • Hostnames that appear and disappear from the network as conflict detection kicks in.
  • Remote Bonjour/Zeroconf clients may:
    • See duplicate or conflicting entries.
    • Randomly pick one, or ignore the host if they detect weirdness.

With mDNS, having multiple stacks on one host is generally discouraged; Avahi’s own docs advise against embedding multiple mDNS stacks on the same system.

3. DNS-SD browsing and publishing failures

Avahi is designed around D-Bus-based DNS-SD:

  • Applications often call:
    • Avahi’s D-Bus interface directly.
    • Or Bonjour-compatible APIs via avahi-compat-libdns_sd.

If you try to lean on systemd-resolved for mDNS/DNS-SD but still have Avahi installed:

  • Some apps will still talk to Avahi and expect it to be authoritative.
  • Others may indirectly trigger systemd-resolved’s mDNS via name lookups.
  • You end up with two partial views of the service set on the LAN.

Result: you can see “missing services” in one app but not another, or services advertised via one stack that aren’t discoverable via the other.

4. Debugging becomes unpleasant

When “hostname.local doesn’t resolve”:

  • With a single mDNS stack, you can:
    • Check Avahi status (systemctl status avahi-daemon).
    • Inspect services in /etc/avahi/services.
    • Confirm nsswitch and nss-mdns configuration.
  • With two stacks:
    • You’re guessing which daemon a given tool is actually hitting.
    • resolvectl may show one picture; Avahi browsers show another.
    • Race conditions and subtle timing issues surface, similar in spirit to the “racing signals with D-Bus object creation” bugs you see when multiple components fight over the same interface.

The net effect is that the failure mode stops being “it never works” and becomes “it sometimes works,” which is far worse in production.


Practical coexistence patterns

If you’re maintaining a distro image or fleet, these are the practical patterns I’d recommend:

  1. Desktop / laptop with rich LAN discovery:

    • Enable Avahi + nss-mdns for mDNS/DNS-SD.
    • Use systemd-resolved for unicast DNS only (disable its mDNS on links where Avahi operates).
    • Ensure /etc/nsswitch.conf sends .local to mdns/mdns_minimal before resolve.
  2. *Minimal server that only needs .local resolution, no DNS-SD:

    • Disable Avahi entirely.
    • Let systemd-resolved handle mDNS for .local.
    • Keep nsswitch simple (hosts: files resolve dns or distro default).
  3. Mixed environment where you need Avahi’s D-Bus API but also rely heavily on systemd-resolved:

    • Run Avahi for mDNS/DNS-SD.
    • Keep systemd-resolved for unicast DNS.
    • Be strict about:
      • Disabling mDNS in systemd-resolved on interfaces where Avahi operates, or
      • Ensuring all mDNS requests go via nss-mdns → Avahi, not systemd-resolved.

Final Verdict

Avahi and systemd-resolved can coexist cleanly, but they should not both simultaneously “own” mDNS/DNS-SD on the same host. For most Linux-first, Bonjour/Zeroconf-style service discovery use cases, running Avahi as the sole mDNS/DNS-SD daemon and wiring *.local lookups through nss-mdns via nsswitch is the most predictable, interoperable setup. systemd-resolved fits best as the general DNS resolver and, in environments that don’t need full DNS-SD, as a simple mDNS provider once Avahi is removed.

If you find yourself debugging inconsistent hostname.local behavior or missing printers/shares, the first step is to decide which daemon is responsible for mDNS/DNS-SD, commit to that choice, and configure the other to stay out of the multicast path.


Next Step

Get Started