[Bug]: iOS app reconnect-loops and threads stay on Syncing over Tailscale Serve on an intermittent connection#24909

opened4d agobyHhomatthew

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/mobile

Steps to reproduce

  1. Run the server as the background service on macOS, bound to 127.0.0.1:3773 and reached through Tailscale Serve. The iPhone app is the only client.
  2. Open the iOS app on a slow or intermittent connection.
  3. Open a thread.

Expected behavior

The environment stays connected, and the thread loads.

Actual behavior

The environment flips between connected and disconnected. An opened thread often stays on "Syncing". When it loads, it first shows an older cached state, then the newer messages. How this goes varies by thread.

Server traces (2026-10-25, UTC). All 50 Tailscale /ws sockets came from this phone (clientSurface=mobile, clientAppVersion=2.1.0, iOS 27, connectionMethod=direct):

  • Median socket life was 62 s, and 43 of 50 lasted 120 s or less. Upgrade auth succeeded every time.
  • In 28 of 49 reconnects, the phone opened the new socket while the server still held the old one (median overlap 21 s).
  • 16 of 50 sockets sent no RPC after subscribeServerConfig.
  • Thread snapshots took 0.1–0.4 s on the server.
  • Each subscribeServerConfig spent about 3.5 s in ws.loadServerConfig, waiting on tailscale.readTailscaleOutput. All 50 calls failed with TailscaleCommandTimeoutError: tailscale status timed out after 3500ms. On this host the tailscale CLI couldn't reach the daemon's socket.

After the host CLI could reach the daemon (16:51–16:55Z, same versions), ws.loadServerConfig took 0.4–1.4 s. The drops continued: sockets lasted 101 s, 71 s and 0 s, with the same overlap.

The iOS app exposes startup crash logs only, not runtime logs, so this is server-side evidence only. No startup crash was recorded. I didn't measure the phone's network or whether its Tailscale path was direct or DERP.

Impact

Major degradation or frequent failure

Version or commit

Server t3 0.1.3-nightly.20261023.3579; iOS app 2.1.0 (164)

Environment

macOS host, Tailscale Serve (userspace tailscaled); iPhone, iOS 27.0.1

Logs or stack traces

text
1server.trace.ndjson, UTC, offsets from /ws upgrade (hosts, tickets, IPs removed)
2
315:25:00Z /ws 101 life=25.8s
4 +0.9s subscribeServerConfig 19.93s Interrupted (loadServerConfig ~3.5s: tailscale status timeout)
5 no other RPC
6 +25.8s markDisconnected
715:25:28Z /ws 101 life=85.5s (opened 1.9s before the server closed the previous socket)
8 +0.9s subscribeServerConfig 83.78s Interrupted
9 +10.0s first other RPCs
10 +11.7s orchestration.subscribeShell 73.01s Interrupted
11 +85.5s markDisconnected
12
1314:26:45Z /ws 101 life=2735.6s (longest socket)
14 +0.8s subscribeServerConfig
15 +8.7s first other RPCs

Related

#24677 (iOS on a high-latency Tailscale route, wakeup probe replacing sessions), #24192 (mobile thread view on Syncing), #16549, #23731, #14519.

Duplicate of #16549, which tracks the iOS app reconnect-loop through Tailscale Serve after successful authentication, including when the server produces configuration promptly. The traces here add evidence on iOS 2.1.0: reconnects continue after the host CLI timeout is resolved. Keeping the investigation in the original issue.