Source: https://mayphus.org/tailscale-subnet-route-acl/ Title: The Tailscale subnet route that was approved but never arrived Metadata: {"category":"note","date":"2026-10-26T00:00:00Z","id":"tailscale-subnet-route-acl","kind":"article","language":"en","locale":"en","route":"/tailscale-subnet-route-acl/","slug":"tailscale-subnet-route-acl","tags":["tailscale","networking","ops"],"type":"article"} My home router advertises the LAN as a Tailscale subnet route. The admin console showed it approved, with the Subnets badge and no warning. "Use Tailscale subnets" was on, on my iPhone. On mobile data, though, the phone still couldn't reach Home Assistant on my home server. Every dashboard said it should work, and it didn't. ## Measure before guessing Instead of toggling settings, I looked at the one place that couldn't lie: the router itself. - Tailscale traffic from the phone was arriving at the router. - Packets to the home server's LAN address: zero. So the tunnel was up, but the phone never sent anything toward the LAN. It wasn't a firewall dropping packets on the router. The phone had never installed the route at all. ## Root cause: the policy, not the route Months earlier I had tightened my tailnet policy, moving away from the allow-all default. It looked roughly like this: - members can reach members - members can reach the internet - a tagged, untrusted laptop can reach the internet and nothing else That reads fine, but it misses three things about how Tailscale works: 1. **Policies deny by default.** Anything not explicitly allowed is blocked. 2. **`autogroup:member` means devices, not networks.** It covers members' Tailscale addresses (the 100.x range), not the subnets behind them. 3. **Routes are filtered by access.** A client only receives a subnet route if the policy allows it to reach that destination. No rule means no route, and the client gets no error, either. So the route was approved, but my policy gave no one access to it, and Tailscale quietly kept it from every client. ## The fix One rule (the subnet here is an example): ```json { "action": "accept", "src": ["autogroup:member"], "dst": ["192.168.1.0/24:*"] } ``` The phone got the route right away, and Home Assistant loaded over mobile data. The untrusted laptop still can't reach the LAN. It's a tagged device, and tagged devices aren't members, so the new rule doesn't apply to it. Tightening the policy earlier was right; it was just incomplete. ## Lessons - **An approved route isn't the same as a route clients can use.** Approval says the router may advertise it, while the access policy decides who receives it. - **Check the data path at the device that's failing.** Zero packets toward the LAN pointed straight at the client's routing table, not at the router's firewall. - **When you tighten a default-allow policy, list everything the old default allowed,** subnets included, and decide on each one deliberately. - **Test from outside after any policy change,** for example from a phone on mobile data, not just from the LAN. It took ten minutes once I stopped trusting dashboards and counted packets.