How do I make hostname.local resolve on Linux using AVAHI + nss-mdns (exact nsswitch.conf lines and packages)?
Networking System Software

How do I make hostname.local resolve on Linux using AVAHI + nss-mdns (exact nsswitch.conf lines and packages)?

7 min read

On a Linux system, making hostname.local resolve reliably is mostly about wiring Avahi’s mDNS/DNS-SD into the standard name service path via nss-mdns. Once the right packages are installed and nsswitch.conf is configured correctly, every CLI tool that uses libc’s resolver will “just know” how to reach *.local peers.

Below is a practical, distro-oriented walkthrough, with exact package names and nsswitch.conf lines you can lift into your environment.


What AVAHI + nss-mdns actually do for hostname.local

Avahi implements mDNS/DNS-SD on your LAN. It lets machines advertise and discover services and hostnames without a central DNS server, using the same Bonjour/Zeroconf protocol family that Apple devices use.

By itself, Avahi does not make hostname.local work in arbitrary programs. That bridge is the nss-mdns module, which:

  • plugs into glibc’s nsswitch mechanism
  • handles *.local lookups via mDNS
  • makes hostname.local resolvable “in all system programs using nsswitch,” not just Avahi-aware clients

The core wiring is:

  • Avahi daemon running
  • nss-mdns installed
  • mdns (or mdns4 / mdns6) present in the hosts: line in /etc/nsswitch.conf

Step 1: Install Avahi and nss-mdns (by distribution)

First, ensure the mDNS/DNS-SD plumbing and nsswitch module are installed. Package names differ slightly per distro, but the pattern is consistent.

Debian / Ubuntu / Linux Mint

sudo apt update
sudo apt install avahi-daemon avahi-utils libnss-mdns
  • avahi-daemon: mDNS/DNS-SD service
  • avahi-utils: CLI tools like avahi-browse, avahi-resolve
  • libnss-mdns: nss-mdns module for *.local in nsswitch

Fedora / RHEL / Rocky / Alma

sudo dnf install avahi avahi-tools nss-mdns

On older RHEL-derived systems that still use yum:

sudo yum install avahi avahi-tools nss-mdns

openSUSE / SUSE Linux Enterprise

sudo zypper install avahi avahi-utils nss-mdns

Arch Linux / Manjaro

sudo pacman -S avahi nss-mdns

Arch often ships with a minimal nsswitch.conf; you’ll wire mdns in explicitly in the next step.


Step 2: Enable and start the Avahi daemon

The Avahi daemon must be running to answer mDNS queries for hostname.local.

sudo systemctl enable avahi-daemon
sudo systemctl start avahi-daemon
sudo systemctl status avahi-daemon

Verify it’s active (running) and not repeatedly restarting. If it’s failing, fix that first; mDNS lookups will not work without it.

On some distributions, a “zeroconf” or “mdns” firewall service must be allowed (UDP 5353). Make sure your local firewall isn’t dropping that traffic.


Step 3: Edit /etc/nsswitch.conf for mDNS

The decisive step: add the mdns module into the hosts: entry in /etc/nsswitch.conf so that glibc will ask nss-mdns for *.local names.

Always back up the file before editing:

sudo cp /etc/nsswitch.conf /etc/nsswitch.conf.bak
sudo nano /etc/nsswitch.conf

Common baseline before changes

You’ll typically see something like:

hosts:          files dns

or:

hosts:          files mdns4_minimal [NOTFOUND=return] dns

Your exact line might include myhostname, resolve, or nis; keep existing entries unless you have a reason to change them.

Exact hosts: lines that work well

Below are patterns that work reliably with Avahi + nss-mdns. Use one that matches your IPv4/IPv6 preferences.

IPv4-only mDNS (mdns4) – recommended on IPv4-only networks

hosts:          files mdns4_minimal [NOTFOUND=return] dns mdns4
  • mdns4_minimal [NOTFOUND=return] lets *.local resolve quickly via mDNS
  • dns remains the primary path for non-local domains
  • mdns4 at the end is a fallback for some edge cases

Dual-stack mDNS (IPv4 + IPv6) – if you actually use IPv6 on LAN

hosts:          files mdns_minimal [NOTFOUND=return] dns mdns

Simple configuration (no minimal module)

If you prefer a straightforward ordering:

hosts:          files mdns4 dns

or:

hosts:          files mdns dns

This is easier to reason about but may alter lookup behavior slightly if you’re mixing *.local with special DNS overrides.

Distro-specific examples

Debian/Ubuntu (modern default + mDNS)

A common and safe configuration:

hosts:          files mdns4_minimal [NOTFOUND=return] dns

If mdns4_minimal isn’t present, change:

hosts:          files dns

to:

hosts:          files mdns4_minimal [NOTFOUND=return] dns

Fedora/RHEL

Suggested:

hosts:          files mdns4_minimal [NOTFOUND=return] dns

or, if you want both IPv4 and IPv6 mDNS:

hosts:          files mdns_minimal [NOTFOUND=return] dns

Arch Linux

Arch’s nsswitch.conf often starts as:

hosts:          files mymachines myhostname resolve [!UNAVAIL=return] dns

You can extend it like this:

hosts:          files mymachines myhostname mdns4_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] dns

or a simpler variant:

hosts:          files mymachines myhostname mdns4 dns

The key is the presence of mdns, mdns4, or mdns_minimal somewhere in the hosts: line.


Step 4: Confirm nss-mdns is actually loaded

To confirm the mdns NSS module is wired in correctly, use getent, which goes through nsswitch:

getent hosts hostname.local

If hostname.local is on your LAN and being advertised via Avahi, you should get something like:

192.168.1.23   hostname.local

If getent returns nothing:

  • re-check /etc/nsswitch.conf for syntax errors
  • confirm libnss_mdns.so.* (or equivalent) exists under /lib or /lib64
  • make sure the Avahi daemon is running and that the target host is actually announcing its name over mDNS

You can also inspect what nss modules are referenced in nsswitch.conf:

grep '^hosts:' /etc/nsswitch.conf

Make sure mdns, mdns4, or mdns_minimal appears in the line.


Step 5: Test from real applications

Because nss-mdns hooks into nsswitch, the same behavior should show up in any program that uses normal libc name resolution.

Test a few:

ping hostname.local
ssh user@hostname.local
curl http://hostname.local:8080/

If getent works but ping or ssh do not, you’re likely dealing with one of:

  • an application using a baked-in resolver that ignores nsswitch
  • a container or chroot with a different nsswitch.conf or missing nss-mdns library
  • statically linked binaries that bypass glibc’s NSS completely

In those scenarios, fix the environment (copy nsswitch.conf, install nss-mdns in the chroot/container) or avoid tooling that bypasses nsswitch for local host lookups.


Step 6: Make sure the host itself advertises its .local name

For hostname.local to resolve, some node has to publish that name on the LAN via mDNS. With Avahi, that is usually:

  • automatic, based on the system hostname, or
  • configured via Avahi’s daemon settings

Check the system hostname

hostnamectl

You’ll see lines like:

Static hostname: hostname
Pretty hostname: hostname

By default, Avahi will announce this host as hostname.local. Adjusting the hostname adjusts the advertised mDNS name.

Inspect Avahi’s published records

Use avahi-browse and avahi-resolve:

# List mDNS services
avahi-browse -a

# Resolve this host by its mDNS name
avahi-resolve -n hostname.local

avahi-resolve -n should yield an IP address. If it does, but getent hosts hostname.local does not, your nsswitch wiring remains the problem. If neither works, look at Avahi’s logs:

journalctl -u avahi-daemon

Common failure modes and how to fix them

1. .local still goes to DNS, not mDNS

Symptom: dig hostname.local hits your upstream DNS and returns NXDOMAIN, and ping hostname.local also fails.

Fix: ensure mdns appears before dns in the hosts: line, or at least that mdns4_minimal [NOTFOUND=return] is in use:

hosts:          files mdns4_minimal [NOTFOUND=return] dns

This tells glibc to short-circuit to mDNS for .local before talking to your traditional DNS servers.

2. Only some tools resolve .local

Symptom: avahi-resolve works, but ping hostname.local does not.

Fix checklist:

  • getent hosts hostname.local must work; if it doesn’t, fix nsswitch.conf
  • if getent works but ping doesn’t:
    • confirm ping is not using a static resolver (on most Linux it doesn’t)
    • check you’re running both commands in the same environment (no container differences)
    • look for multiple nsswitch.conf or chroot-specific config

3. Mixed IPv4/IPv6 behavior

If you have IPv6 enabled but don’t have v6 connectivity on the LAN, prefer mdns4/mdns4_minimal to avoid timeouts on AAAA queries:

hosts:          files mdns4_minimal [NOTFOUND=return] dns

This restricts mDNS handling to IPv4 and tends to be more predictable on dual-stack systems that are effectively IPv4-only on the LAN.


Exact minimal recipe: make hostname.local work everywhere

To summarize a “just give me the exact lines” setup that works on most modern Linux distributions:

  1. Install the necessary packages:

    # Debian/Ubuntu
    sudo apt install avahi-daemon avahi-utils libnss-mdns
    
    # Fedora/RHEL
    sudo dnf install avahi avahi-tools nss-mdns
    
    # Arch
    sudo pacman -S avahi nss-mdns
    
  2. Enable and start Avahi:

    sudo systemctl enable avahi-daemon
    sudo systemctl start avahi-daemon
    
  3. Set hosts: in /etc/nsswitch.conf to:

    hosts:          files mdns4_minimal [NOTFOUND=return] dns
    
  4. Test resolution:

    getent hosts hostname.local
    ping hostname.local
    

Once this is in place, hostname.local will resolve via mDNS in all system programs using nsswitch, backed by Avahi’s mDNS/DNS-SD implementation. If you hit edge cases beyond this, checking Avahi’s logs and the nss-mdns GitHub repository is usually the next debugging step.

Next Step

Get Started