
How do I browse and resolve services with AVAHI from the command line to validate discovery on a test LAN?
Validating Avahi on a test LAN from the command line is mostly about doing two things: confirming that mDNS/DNS-SD browsing works, and verifying that you can resolve advertised services and hostnames. You don’t need to touch the D-Bus API directly for this; Avahi ships CLI tools that exercise the same discovery paths applications use.
Below is a practical sequence I use when I’m debugging “why doesn’t anything show up?” on real fleets.
All commands assume a Linux system where Avahi is installed and running. Avahi is primarily targeted at Linux and ships by default in most distributions; it is not ported to Windows at this stage.
1. Confirm Avahi and mDNS are actually running
Before testing discovery, confirm that the Avahi daemon and your network interface are in a usable state.
Check that avahi-daemon is up
On systemd-based systems:
systemctl status avahi-daemon.service
You want to see it active (running). If not:
sudo systemctl start avahi-daemon.service
sudo systemctl enable avahi-daemon.service # optional, for boot
On non-systemd systems, use the service mechanism your distro provides, or run:
ps aux | grep avahi-daemon
You should see the daemon process.
Check that you have a usable network interface
mDNS is link-local. If you’re testing on a wired or Wi‑Fi LAN, make sure the interface is up and has an IP address (IPv4 or IPv6):
ip addr
You don’t need Internet routing; you just need to be on the same L2 segment as your peers.
2. List all discovered services with avahi-browse
The primary CLI tool for “what’s on the LAN?” is avahi-browse. It uses the same mDNS/DNS-SD mechanisms Avahi exposes via D‑Bus.
Basic full browse (good first test)
avahi-browse -a
Key flags that are useful for quick validation:
-a— browse all service types-r— resolve services to get host, port, and TXT records-t— terminate after the initial browse (don’t stay running)
A good first diagnostic:
avahi-browse -art
What you should see (on a non-empty LAN) looks like:
+ eth0 IPv4 Office Printer @ 1st Floor _ipp._tcp local
= eth0 IPv4 Office Printer @ 1st Floor _ipp._tcp local
hostname = [printer-1.local]
address = [192.168.10.45]
port = [631]
txt = ["txtvers=1" "Color=T" "Duplex=F"]
If you see nothing at all, jump down to the troubleshooting section.
Browse a specific service type
Once you know what DNS‑SD type you care about (e.g. IPP printing, SMB file sharing), narrow the browse:
- IPP/IPP Everywhere printers:
_ipp._tcp - AirPrint / IPP printing variants:
_ipp._tcp,_ipps._tcp - SMB file sharing:
_smb._tcp - SSH (if advertised by peers):
_ssh._tcp - SFTP (if advertised):
_sftp-ssh._tcp
Example: list printers only, don’t resolve:
avahi-browse -t _ipp._tcp
Same, but resolve each service:
avahi-browse -rt _ipp._tcp
You should see hostname, address, port, and txt blocks for each discovered printer.
Browse IPv4 vs IPv6 explicitly
If you suspect v4/v6 issues:
avahi-browse -art4 # IPv4 only
avahi-browse -art6 # IPv6 only
Discrepancies between these two often reveal firewalling or interface issues.
3. Inspect available service types with avahi-browse -k
Sometimes you don’t know what service types are present; you just want to see the DNS‑SD “catalog”.
Use:
avahi-browse -k
This prints a list of service types, not actual instances, for example:
+ eth0 IPv4 _airplay._tcp _services._dns-sd._udp local
+ eth0 IPv4 _ipp._tcp _services._dns-sd._udp local
+ eth0 IPv4 _smb._tcp _services._dns-sd._udp local
Once you know the type (say _airplay._tcp), plug it back into avahi-browse -rt _airplay._tcp to see specific services.
4. Verify *.local hostname resolution with avahi-resolve and nss-mdns
Browsing shows you services. Resolution confirms that hostnames like printer-1.local or laptop.local can be turned into IP addresses, which is where nss-mdns comes in.
Check that nss-mdns is installed and wired into nsswitch
On most distros:
grep mdns /etc/nsswitch.conf
You want something like:
hosts: files mdns_minimal [NOTFOUND=return] dns
or:
hosts: files mdns dns
If mdns (or mdns_minimal) is missing, install nss-mdns from your distro and update /etc/nsswitch.conf. This is what makes *.local hostnames resolvable “for all system programs using nsswitch” (ping, ssh, curl, etc.).
Resolve hostnames using avahi-resolve-host-name
From Avahi’s tooling:
avahi-resolve-host-name printer-1.local
Expected output:
printer-1.local 192.168.10.45
Try IPv6 too:
avahi-resolve-host-name -6 printer-1.local
If avahi-browse -rt shows a hostname but avahi-resolve-host-name cannot resolve it, you likely have a multicast or firewall issue on the LAN.
Resolve hostnames using normal system tools
Once nss-mdns is wired in, test using standard tools:
ping printer-1.local
ssh user@laptop.local
curl http://fileserver.local:8080/
These tools don’t know about mDNS directly; they just call the system resolver. If they work, you’ve validated end-to-end integration: mDNS via Avahi → nsswitch via nss‑mdns → normal applications.
5. Resolve services to host/port pairs from the CLI
Sometimes you want to go the other direction: starting from a known service instance name (e.g. “Office Printer @ 1st Floor”), get the host and port.
Use avahi-browse with resolve
The simplest mode is the one we already used:
avahi-browse -rt _ipp._tcp
That prints, for each service:
- Instance name:
Office Printer @ 1st Floor - Service type:
_ipp._tcp - Domain:
local - Hostname:
printer-1.local - IP address:
192.168.10.45 - Port:
631 - TXT records
That’s effectively “discover + resolve” in one step.
Use avahi-resolve-address for reverse lookups
If you have an IP from elsewhere and want to see if a .local name exists:
avahi-resolve-address 192.168.10.45
If there’s an mDNS name, you’ll get something like:
192.168.10.45 printer-1.local
This is useful when you’re trying to cross-check a static IP inventory against what mDNS/DNS-SD is advertising.
6. Validate Avahi from inside the LAN and across subnets
mDNS operates on link-local multicast; by design, it doesn’t cross traditional L3 boundaries. For a test LAN, that usually means:
- All peers must be on the same VLAN / broadcast domain.
- IGMP snooping and mDNS snooping on switches must not block 224.0.0.251 / ff02::fb.
Sanity checks on multiple machines
From machine A:
avahi-browse -art
From machine B on the same subnet:
avahi-browse -art
You should see at least each other’s hostnames or exposed services if you’ve configured any (for example via XML in /etc/avahi/services or a D‑Bus publisher).
If A sees B but B doesn’t see A:
- Check host firewall rules on A (e.g.
iptables,nftables,firewalld,ufw). - Ensure Avahi is listening on the correct interfaces; check
server.confin/etc/avahi.
7. Quickly publish a test service and see it from the CLI
To validate discovery end-to-end, it helps to publish a known test service on one node and confirm it’s visible from others.
7.1 Publish via /etc/avahi/services XML
This uses Avahi’s static XML interface, which is the simplest for quick tests.
Create /etc/avahi/services/test-http.service:
<?xml version="1.0" standalone='no'?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
<name replace-wildcards="yes">%h Test HTTP</name>
<service>
<type>_http._tcp</type>
<port>8080</port>
<txt-record>path=/</txt-record>
</service>
</service-group>
Then restart Avahi:
sudo systemctl restart avahi-daemon.service
On another machine on the same LAN:
avahi-browse -rt _http._tcp
You should see something like:
+ eth0 IPv4 myhost Test HTTP _http._tcp local
= eth0 IPv4 myhost Test HTTP _http._tcp local
hostname = [myhost.local]
address = [192.168.10.50]
port = [8080]
txt = ["path=/"]
If that works, discovery, resolution, and your XML service publication path are all functioning.
7.2 Publish dynamically via avahi-publish
For a transient test without editing /etc:
avahi-publish -s "My Temp HTTP" _http._tcp 8080 "path=/"
This keeps running in the foreground while advertising the service. From another machine:
avahi-browse -rt _http._tcp
You should see the “My Temp HTTP” instance. Once you Ctrl‑C the avahi-publish command, the service disappears from browse results.
8. Common failure modes and how to see them from the CLI
When your goal is to “validate discovery on a test LAN,” it helps to tie typical observations back to probable causes.
Symptom: avahi-browse -art shows nothing at all
Likely causes:
avahi-daemonis not running.- You’re on a very quiet LAN with no Avahi/Bonjour devices.
- The system’s interfaces are down or in a strict firewall zone that drops multicast.
Quick checks:
systemctl status avahi-daemon
ip addr
sudo iptables -L -n
sudo nft list ruleset
Try temporarily reducing firewall restrictions on the test LAN node and re-run avahi-browse -art.
Symptom: You see services, but ping hostname.local fails
Likely causes:
nss-mdnsnot installed or not wired in/etc/nsswitch.conf./etc/nsswitch.confordersdnsbeforemdnsand your upstream DNS returns NXDOMAIN or another answer.- The host only has IPv6 and your test tool is forcing IPv4, or vice versa.
Checks:
grep hosts /etc/nsswitch.conf
avahi-resolve-host-name hostname.local
ping -4 hostname.local
ping -6 hostname.local
If avahi-resolve-host-name works but ping doesn’t, it’s almost always an nsswitch configuration issue.
Symptom: Some tools see .local hosts, others don’t
This indicates inconsistency in how those tools use the resolver libraries.
Because nss-mdns hooks into nsswitch, you want to be sure everything is going through glibc’s getaddrinfo(3) path. If a specific tool does its own DNS resolution or is linked differently, it might bypass mdns.
For test LAN validation, focus on:
avahi-browse -art
avahi-resolve-host-name <name>.local
ping <name>.local
ssh <name>.local
If these work, the core Avahi + nss-mdns path is healthy.
9. Mapping CLI tests to real LAN use cases
To recap in terms of concrete LAN scenarios Avahi targets:
-
Finding printers to print to
avahi-browse -rt _ipp._tcp avahi-browse -rt _ipps._tcp avahi-resolve-host-name <printer>.local -
Finding files being shared
For SMB/CIFS:
avahi-browse -rt _smb._tcp avahi-resolve-host-name <fileserver>.localThen mount or connect using the resolved hostname and port.
-
Peer discovery for custom apps
If your application publishes
_myapp._tcpvia D‑Bus or/etc/avahi/services, validate with:avahi-browse -rt _myapp._tcp avahi-resolve-host-name <peer>.localThis mirrors what your peer clients should see programmatically via the D‑Bus API.
Final verdict
To validate Avahi service discovery on a test LAN from the command line:
- Use
avahi-browse -artas your primary sanity check to see all mDNS/DNS-SD services and confirm discovery works. - Narrow to specific types (e.g.
_ipp._tcp,_smb._tcp) and add-rto confirm that service instances resolve to host/port pairs. - Wire up
nss-mdnsand verify*.localhostnames withavahi-resolve-host-nameand standard tools likepingandssh. - Optionally publish a simple test service via
/etc/avahi/servicesoravahi-publishand confirm it appears in browse results from another host.
Once those steps succeed, you’ve validated that Avahi’s mDNS/DNS-SD stack, hostname resolution, and CLI tooling are working correctly on your test LAN.