← All Articles

Don't Use .local for Your Homelab Domain

Using .local for your homelab DNS zone puts you in direct conflict with mDNS (Bonjour/Avahi). Here's why resolution breaks intermittently and what to use instead.

networkingnetworkingtechnitiumbeginner

I ran homelab.local as my internal DNS zone for about six months before I figured out why my iPad kept failing to resolve services that worked fine on every other device. Sometimes it resolved. Sometimes it timed out. Rebooting the iPad fixed it temporarily, then it would break again. The services themselves were fine. The DNS server was fine. But .local was the problem, and I had no idea.

Here’s what was actually happening, and what I switched to.

What mDNS is and why .local belongs to it

Multicast DNS (mDNS) is a protocol that allows devices to resolve hostnames on a local network without a central DNS server. It works by multicast: a device broadcasts “who is printer.local?” to the whole network, and printer.local answers directly.

Apple devices use this for Bonjour. Linux devices use it through Avahi. Chromecast devices use it. Lots of IoT hardware uses it. It’s the mechanism that makes your AirPrint printer discoverable, that lets you find a new Raspberry Pi at raspberrypi.local before you’ve configured anything, and that makes a lot of “just works” local discovery actually work.

RFC 6762 reserves .local for exactly this purpose. The spec is explicit: .local is a special-use domain for mDNS. It is not a normal TLD you can assign arbitrary meaning to. When a resolver sees a hostname ending in .local, it is supposed to use mDNS rather than standard DNS.

When you create a DNS zone called homelab.local and start adding records to it, you’re creating a conflict. Some clients will use your DNS server. Some will use mDNS. Some will try mDNS first, fall back to DNS, or do both in parallel and use whichever responds first. The behavior varies by OS, version, and configuration.

The failure mode

The symptoms are intermittent and hard to diagnose because they don’t fail consistently.

On a typical home network, a Mac or iPad will try mDNS for any .local hostname before it tries conventional DNS. If mDNS doesn’t return an answer quickly (because nothing on the network is advertising that hostname via mDNS), the device may fall back to DNS. Or it may not, depending on timing and system state. The mDNS timeout behavior is inconsistent across Apple platforms and has changed between OS versions.

The result: proxmox.homelab.local resolves fine from your Linux desktop running systemd-resolved with the right DNS configuration, resolves intermittently from your Mac, and fails unpredictably from your iPhone. You spend time troubleshooting your DNS server, your NPM config, your SSL certs, and none of that is the problem.

Apple devices are the most visible because Bonjour runs aggressively on macOS and iOS. But any device running Avahi (common on Raspberry Pi OS, Ubuntu, most Linux desktops) will have the same issue. The .local conflict is protocol-level, not vendor-specific.

.lan as the practical alternative

.lan has no reserved meaning. No protocol claims it. No RFC assigns it special behavior. When a device sees a hostname ending in .lan, it queries DNS and only DNS.

It is not an official TLD. ICANN has never assigned it. That’s actually what you want for an internal domain: something that won’t accidentally resolve to a real internet hostname if your DNS server is unreachable, and something no protocol has already claimed.

.lan is the most common choice in the homelab community for exactly this reason. It’s short, it’s recognizable, and it works. proxmox.homelab.lan, npm.homelab.lan, dns.homelab.lan all route through your DNS server with no protocol conflict.

.home.arpa if you want the official answer

IETF published RFC 8375 in 2018, which reserves .home.arpa specifically for residential and small-network use. This is the standards-body answer to the same problem. If you want an internal domain that is formally documented as intended for home use and will never be assigned to public internet traffic, .home.arpa is it.

In practice, .home.arpa sees less adoption than .lan in homelab setups. It’s longer, the dot-in-the-middle trips people up in some configuration files, and .lan already works well with no downsides. I mention it because you’ll see it referenced in technical documentation and it’s worth knowing it exists. For a home lab running Technitium, Nginx Proxy Manager, and Tailscale, .lan is the simpler choice with identical practical benefits.

Setting this up in Technitium

If you’re starting fresh, this is straightforward. If you’re migrating from .local, it’s a bit more work but not much.

The Technitium DNS setup guide covers initial configuration in detail. For the zone itself:

  1. Open the Technitium web UI and go to Zones.
  2. Click Add Zone. Enter your zone name as homelab.lan (or whatever subdomain you prefer, like lan by itself if you want bare server.lan hostnames).
  3. Set zone type to Primary Zone.
  4. Add your A records: each service hostname pointing to its internal IP.

That’s the core of it. Technitium will authoritatively answer queries for anything in homelab.lan and clients with your DNS server configured will resolve them correctly, every time, on every device.

If you’re migrating from .local, create the new .lan zone and duplicate your records there before removing the old zone. Update services and bookmarks one at a time so nothing breaks simultaneously.

Updating NPM and Tailscale split DNS

Two other places need to know about the domain change.

Nginx Proxy Manager: Each proxy host has a domain name field. Update these to the .lan equivalents. SSL certs issued via DNS challenge (Cloudflare) don’t care about the TLD, so re-issuing against the new hostnames works the same way.

Tailscale split DNS: In the Tailscale admin panel under DNS settings, update the split DNS entry to route homelab.lan (or your chosen zone) to your Technitium server’s IP. This is what makes your .lan hostnames resolve correctly when you’re connected to Tailscale from outside your network. Remove the old .local entry if you had one configured.

After both are updated, .local is out of the picture entirely and you won’t fight the mDNS conflict again.

The short version

.local is reserved by RFC 6762 for mDNS. When you use it for DNS, you’re competing with a protocol that is baked into Apple devices, Linux desktops, and a lot of IoT hardware. The failure mode is intermittent and annoying to diagnose. Use .lan instead. It has no reserved meaning, no conflicting protocol, and your DNS server always wins.