Fix .local resolve on Ubuntu
# `.local` (mDNS) resolution on Ubuntu 24.04 — troubleshooting aide
Setup assumed: LAN interface (e.g. `enpXsY`), a Docker bridge (`docker0` — ignore it).
Goal: resolve `myserver.local` etc. via mDNS, falling back to a local/unix DNS server for the LAN.
## Symptoms
```
resolvectl query myserver.local
myserver.local: resolve call failed: No appropriate name servers or networks for name found
```
## Diagnose
```bash
resolvectl status
```
Read two levels:
1. **Global** — `Protocols: +mDNS` means mDNS is enabled globally.
2. **Per-link** — the LAN interface must show `mDNS/DNS-SD` in `Current Scopes`.
⚠️ Per-link settings **override** the global section. Typical failure:
global `+mDNS` but the LAN link shows `-mDNS` (another link, e.g. a bridge,
may correctly show `+mDNS`).
## Fix
### 1. Enable mDNS globally (persistent)
`/etc/systemd/resolved.conf` (or a drop-in so the main file stays clean):
```bash
sudo mkdir -p /etc/systemd/resolved.conf.d
sudo tee /etc/systemd/resolved.conf.d/mdns.conf <<'EOF'
[Resolve]
MulticastDNS=yes
LLMNR=yes
EOF
sudo systemctl restart systemd-resolved
```
### 2. Enable mDNS on the LAN link (if still `-mDNS` after step 1)
```bash
sudo resolvectl mdns <LINK> yes # <LINK> = link number from `resolvectl status` (e.g. 2)
```
This is **ephemeral** (survives daemon restart, may not survive reboot).
If it reverts after reboot, find the persistent per-link source:
```bash
grep -ri "mdns" /run/systemd/network/ /etc/systemd/network/ /etc/netplan/ 2>/dev/null
```
- `/etc/systemd/network/*.network` → set `MulticastDNS=yes` in the `[Link]` section of the matching file, `sudo systemctl restart systemd-networkd`
- netplan (`/etc/netplan/*.yaml`) → fix YAML, `sudo netplan apply`
### 3. Verify
```bash
resolvectl status # LAN link → Current Scopes: ... mDNS/DNS-SD
resolvectl query myserver.local
```
## If mDNS scope is up but queries still fail
mDNS is multicast and **peer-to-peer**: it only works if the target host is
actively *publishing* its name.
- Publishes by default: macOS, Raspberry Pi, Synology, many NASes, phones.
- Does NOT publish by default: plain Ubuntu/Debian servers (needs avahi-daemon),
most Linux servers, often Windows servers.
Check what's publishing:
```bash
sudo apt install avahi-utils
avahi-browse -a
```
If the target isn't listed, mDNS will never resolve it — use unicast DNS:
```bash
sudo resolvectl dns <LINK> <your-dns-server-ip> # ephemeral
```
Persistent: `DNS=<ip>` in the matching `.network` file, or `nameservers:`
in the netplan YAML.
## Pitfalls (learned the hard way)
- **Do NOT edit `/etc/resolv.conf`** — it's a symlink to
`/run/systemd/resolve/stub-resolv.conf`, auto-regenerated on every
systemd-resolved restart, and it doesn't parse INI sections at all.
Config lives in `/etc/systemd/resolved.conf` + `/etc/systemd/resolved.conf.d/*.conf`.
- `resolvectl` (query/control) ≠ `resolvconf` (legacy tool, not used here).
- If `resolved.conf` says "Managed by NetworkManager" but NM isn't running,
the header is stale — edit it directly. If NM *is* running, use
`/etc/NetworkManager/NetworkManager.conf.d/` with `mdns=both` in `[main]`.
- mDNS doesn't cross subnets/VLANs or Wi-Fi client-isolation.