Diagnose and fix Tailscale subnet router connectivity failures. Runs seven sequential checks covering the full route lifecycle from advertisement through return path verification.
What this skill does
- Verifies the subnet router advertises the route.
- Confirms the route is approved (admin console or autoApprovers).
- Checks that clients accept subnet routes (
--accept-routes). - Inspects policy routing table 52 for installed routes.
- Validates IP forwarding is enabled on the subnet router.
- Tests that the subnet router can reach the target directly.
- Verifies the return path for response traffic.
Common triggers
- Client can ping the subnet router but not devices on the advertised subnet
- Route shows approved in admin console but
ip routeis empty - Docker containers fail to advertise routes via
TS_ROUTES - Traffic flows to the target but responses never come back
- "It works from the router itself but not from other clients"
Diagnostic workflow
Run each step in order. Stop at the first failure and apply the fix before continuing — later steps depend on earlier ones.
Step 1 — Verify route is advertised
tailscale status --json | jq '.Self.AllowedIPs'
Pass: Subnet CIDR appears in AllowedIPs (e.g., 10.100.0.0/24).
Fail: Only Tailscale IPs shown. Route not advertised.
Fix: tailscale set --advertise-routes=<CIDR>. In Docker, check
TS_ROUTES env var — it may not take effect if auth failed on first
boot. Fall back to tailscale set at runtime.
Step 2 — Verify route is approved
Check admin console, or from a peer node:
tailscale status --json | jq '.Peer[] | select(.HostName=="<router>") | .AllowedIPs'
Pass: Subnet CIDR appears in the peer's view of the router's AllowedIPs.
Fail: Only Tailscale IPs shown from peer perspective. Route is pending approval.
Fix: Approve in admin console, or add autoApprovers to ACL:
"autoApprovers": {
"routes": { "10.100.0.0/24": ["tag:subnet"] }
}
Step 3 — Verify client accepts routes
tailscale debug prefs | grep -i route
Fail: --accept-routes is false (the default). Clients ignore
advertised subnet routes even when approved.
Fix: tailscale set --accept-routes=true. In Docker, add
--accept-routes to TS_EXTRA_ARGS. Do not use tailscale down in
Docker — it kills containerboot. Use tailscale set instead.
Step 4 — Verify route in policy routing table
ip route show table 52
Pass: Shows route for subnet CIDR via dev tailscale0.
Fail: Table 52 is empty or missing the subnet route.
Critical: ip route (no table) only shows the main table. Tailscale
uses policy routing table 52 — routes will NOT appear in default output.
This is the most common false negative.
Also check:
ip rule show
See references/policy-routing.md for details on table 52 and how
Tailscale's policy routing works.
Step 5 — Verify IP forwarding on the subnet router
cat /proc/sys/net/ipv4/ip_forward
Pass: Returns 1.
Fail: Returns 0. Kernel drops forwarded packets silently.
Fix: sysctl -w net.ipv4.ip_forward=1. In Docker Compose, set
sysctls: [net.ipv4.ip_forward=1]. For persistence on Linux hosts,
add to /etc/sysctl.d/.
Step 6 — Verify network path from subnet router to target
From the subnet router:
ping <target-ip>
ip addr show
Pass: Router can reach the target and has an interface on the advertised subnet.
Fail: Router cannot reach the target. This is a local network issue (firewall, VLAN, routing) — not Tailscale.
Step 7 — Verify return path
The target must route responses back through the subnet router. If the target's default gateway is not the subnet router, return traffic takes a different path and gets dropped.
Fix: Add a static route on the target (or its gateway) for
100.64.0.0/10 pointing to the subnet router's internal IP. Or enable
masquerading:
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
Tailscale 1.64+ enables --snat-subnet-routes by default, which
handles this automatically.
Error handling
Do not silently skip a failed check. Report the specific failure with the fix before continuing. If a fix requires restarting Tailscale or recreating a container, instruct the user to do so and rerun from step 1.
References
references/route-lifecycle.md— full 7-stage route lifecycle from advertisement through return pathreferences/policy-routing.md— table 52, ip rule, VRF analogy, and whyip routemisses Tailscale routesreferences/common-failures.md— symptom-based lookup table with root causes and fixes