tailscale / tailscale/tailscale

disco: IPv6 ping failure does not fall back to IPv4, causing stuck DERP relay

Open
#20,102 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Go
Stars
36.5k
Forks
3.2k
Avg merge
2d 3h
Merged PRs (30d)
123

Description

## What is the issue?

When a peer has both IPv4 and IPv6 endpoints, the disco protocol sends pings to all of them. However, if the IPv6 ping fails (e.g. `sendto: network is unreachable`), **the disco protocol does not fall back to the available IPv4 endpoints**, resulting in the connection stuck on DERP relay indefinitely.

## Steps to reproduce

1. Peer A is on an IPv4-only network (no IPv6 connectivity)
2. Peer B is on a dual-stack network (has both public IPv4 and IPv6 addresses)
3. Both peers register their endpoints with the coordination server
4. Peer A receives Peer B's endpoints (mixed IPv4 + IPv6)
5. Peer A attempts disco pings — prefers IPv6, fails with `network is unreachable`
6. IPv4 endpoints are never tried, connection stays on DERP relay

## Observed behavior

From Peer A (iStoreOS, Tailscale v1.98.4) syslog:

```
magicsock: disco: failed to send ping to [240e:47b:...]:41641:
write udp6 [::]:41641->[240e:47b:...]:41641: sendto: network is unreachable
```

Peer A has `netcheck: IPv6: no, but OS has support`. It receives Peer B's endpoints from the coordination server:

```json
"Endpoints": [
"49.78.48.12:63335",
"49.78.48.12:41641",
"[240e:47b:240:184c:...]:41641",
"49.78.48.12:63261"
]
```

Despite having valid IPv4 endpoints, disco never attempts any of them after the IPv6 failure.

## Expected behavior

The disco protocol should try all endpoints and use whichever one works. If IPv6 pings fail consistently, it should immediately try IPv4 endpoints and establish a direct connection over IPv4.

## Workaround

Disabling IPv6 on the dual-stack peer (Peer B) so that only IPv4 endpoints are reported to the coordination server. After this, disco immediately establishes a direct IPv4 connection.

## Version

- Peer A (IPv4-only): Tailscale v1.98.4 on iStoreOS (OpenWrt x86_64)
- Peer B (dual-stack): Tailscale v1.96.3 on Windows 11

## Related issues

- #10777 (similar no-fallback behavior with Mullvad exit nodes)
- #15041 (FR for connection priority configuration)
- #1566 (original IPv6 preference implementation)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.