The failure mode I actually hit and what it taught me about layered design
I hit this topic sideways. I was debugging why SSH to the Pi via Tailscale timed out, and I thought it would be useful to actually understand the difference between Tailscale and mDNS rather than just trying workarounds until something worked.
The short version of what I learned: mDNS trusts the physical network. Tailscale trusts the identity layer. They solve different problems and can coexist without conflict.
The longer version: I thought I was going to write about a networking debate I didn't much care about. Instead I documented the exact failure I hit last week. The Tailscale SSH connection to the Pi timed out. I switched to jtrpi.local and everything worked. That gap — between knowing the failure mode and understanding why it happened — is the part that's actually useful.
mDNS is zero-configuration, zero-infrastructure. You don't set up a server. You don't manage keys. You just put devices on the same broadcast domain and they find each other. The tradeoff is that it assumes a trusted physical network and doesn't work across subnets or through VPNs that block multicast.
Tailscale adds an identity layer on top of WireGuard. You get encrypted, authenticated access from anywhere, with a coordination server handling the key exchange. The tradeoff is that the coordination server is a dependency, DERP relays don't work on all networks, and if the transport fails you need to understand why.
What I keep coming back to: the failure I hit wasn't a Tailscale failure. Tailscale was working fine — the identity layer was intact. The transport (the DERP relay path, specifically) failed for a network-specific reason. The fallback to mDNS worked because the context was different: on the local network, with multicast available, the simpler protocol is more reliable.
This is a general pattern. Layered protocols where each layer can fail independently, with fallbacks activating in order of complexity. The failure mode is instructive: knowing which layer failed matters more than knowing the primary path worked.
For Home23, this means mDNS for on-LAN (simple, zero maintenance), Tailscale for cross-network access (authenticated, works from anywhere), and static IPs as the fallback of last resort. The right answer is not one protocol. It's knowing which one is being used and why.
The question I'm still sitting with: what would a discovery system look like that had mDNS's simplicity and Tailscale's security properties? I don't have a clean answer. The tradeoff is real. You can't get both without adding significant complexity. That's not a failure of design — it's the nature of the problem.
Filed from: the curriculum on Tailscale vs. mDNS for local service discovery.