tailscale / tailscale/tailscale
Peer Relay never selected — grant correctly configured, network path confirmed open, client never attempts connection
- Dominant language
- Go
- Stars
- 36.5k
- Forks
- 3.2k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 123
Description
### What is the issue?
## What is the issue?
Peer Relay (GA'd February 2026) is fully configured per the [[official docs](https://tailscale.com/docs/features/peer-relay)](https://tailscale.com/docs/features/peer-relay): the relay node is listening on the configured port, the ACL grant matches the documented example syntax exactly (`grants[].app: {"tailscale.com/cap/relay": []}`), and correct tags are applied to all involved devices (confirmed in the admin console's Machines list, not just assumed).
Despite this, the client device never attempts to use the peer relay. Not a single UDP packet reaches the relay's port during connection attempts — confirmed via `tcpdump` on the relay host while the client was actively trying to reach a peer. `tailscale ping` between the two peers consistently reports `via DERP(...)`, never `via peer-relay(...)`, across 30+ consecutive pings in a single burst, and across multiple independent test sessions spanning several hours.
Separately confirmed the network path itself is not the problem: a raw UDP packet sent manually (bypassing Tailscale entirely, via `nc -u`) from the client's network to the relay's public IP:port arrives cleanly at the relay (observed in `tcpdump`), ruling out any cloud-provider or firewall blocking.
Also worth noting: the same client tailnet has other device pairs that **do** achieve genuine direct (hole-punched) connections some of the time with the same peer device, so basic NAT traversal / magicsock functionality is otherwise healthy on this tailnet — it specifically looks like the peer-relay code path is never being engaged for this pairing, despite every documented prerequisite being met.
This matches an [[unanswered Unraid community thread](https://forums.unraid.net/topic/197306-peer-relay-wont-work/)](https://forums.unraid.net/topic/197306-peer-relay-wont-work/) from shortly after GA describing the identical symptom (grant correct, port forwarded, DERP/direct only, peer relay never used), and is adjacent to but distinct from [[tailscale/tailscale#18851](https://github.com/tailscale/tailscale/issues/18851)](https://github.com/tailscale/tailscale/issues/18851) (Windows + exit-node specific) and [[tailscale/tailscale#20137](https://github.com/tailscale/tailscale/issues/20137)](https://github.com/tailscale/tailscale/issues/20137) (LXC-reboot specific — tried that workaround, did not resolve this case).
Ruled out during troubleshooting: relay not listening (it is, confirmed via `ss -ulnp` on both v4/v6); firewall blocking, at both cloud-edge and host level (confirmed open, and raw UDP reachability independently verified); client version below the 1.86 minimum (all three nodes are 1.98.9–1.102.2); ACL syntax error (matches official docs example and a second independent official reference doc verbatim); incorrect tag assignment (verified in Machines list); Peer Relay gated behind a Feature Preview/invite-only toggle (checked, not applicable — feature is GA); stale netmap/cache (ruled out via full `tailscale down`/`tailscale up`, not just a service restart, on **both** the relay and client nodes); `--relay-server-static-endpoints` override (tried explicitly, no change); insufficient ping attempts (30 consecutive pings, zero upgrades, vs. Tailscale's own [[blog post about this exact CGNAT/relay use case](https://tailscale.com/blog/peer-relays-international-networks)](https://tailscale.com/blog/peer-relays-international-networks) which shows the upgrade happening within 2–3 pings).
All three of the involved tailscale machines are above the documented 1.86 minimum for both hosting and consuming a peer relay.
Happy to provide a `tailscale bugreport` identifier and/or additional `tailscaled` journal excerpts on request — omitted proactively here to keep real IPs/hostnames out of a public post.
### Steps to reproduce
1. Provision a VPS with a public IPv4 (no VPC/NAT/load balancer) as a peer relay: `tailscale set --relay-server-port=41641`.
2. Open the UDP port at both the cloud provider's edge firewall and the host firewall (`ufw`), confirmed listening via `ss -ulnp`.
3. Tag the relay node and the client node, and add the ACL grant:
```json
{
"tagOwners": {
"tag:jf-lxc": ["autogroup:admin"],
"tag:vps-relay": ["autogroup:admin"]
},
"grants": [
{
"src": ["autogroup:member", "tag:jf-lxc"],
"dst": ["*"],
"ip": ["*"]
},
{
"src": ["autogroup:member", "tag:jf-lxc"],
"dst": ["tag:vps-relay"],
"app": {
"tailscale.com/cap/relay": []
}
}
]
}
```
4. From the client (an LXC container on a home LAN behind CGNAT), run `tailscale ping ` while the peer (iOS, on cellular data, confirmed Wi-Fi off) is active.
5. Observe: every ping reports `via DERP(...)`. Run `sudo tcpdump -i any -n udp port 41641` on the relay simultaneously — zero packets arrive.
### Are there any recent changes that introduced the issue?
No — this is a first-time setup, not a regression. The relay VPS was newly provisioned specifically to test Peer Relay, which itself only reached General Availability in February 2026. There is no prior working configuration that changed; the feature has never worked for this device pairing since initial setup, despite matching the documented configuration exactly.
### OS
Linux
### OS version
- Relay node: Debian 13 (Vultr VPS, public IPv4, no VPC) - Client node: Debian-based LXC container (Proxmox host) - Peer node: iOS 26.5.2
### Tailscale version
- Relay node: 1.102.2 - Client node: 1.102.2 - Peer node: 1.98.9- Relay node: 1.102.2 - Client node: 1.102.2 - Peer node: 1.98.9
### Other software
- Host-level firewall on the relay node: `ufw` (default-deny incoming, explicit allow for SSH and the relay UDP port)
- Cloud-edge firewall: Vultr Cloud Firewall (same two allow rules, default-drop otherwise)
- Client node is an unprivileged LXC container on a Proxmox host, no other VPN/mesh networking software installed alongside Tailscale
- No other overlay network, VPN client, or third-party firewall/security software running on any of the three nodes that would be expected to interfere with UDP traffic
### Bug report
BUG-e6e9374095cba36884e2c4d23078f3398db5db2269be4bff25f619f6bab54fc5-20260808144125Z-e64c47f2ba3c037e
Contributor guide
Research direction
Reproduce the documented setup with `tailscale set --relay-server-port=41641`, the supplied ACL grant, `tailscale ping`, and `tcpdump` on UDP port 41641. Start by inspecting the provided `tailscale bugreport` identifier and `tailscaled` journal excerpts to determine why peer-relay selection is skipped. Done means the client attempts the relay and `tailscale ping` reports `via peer-relay(...)` under the stated conditions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, ios, linux
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100