Repository navigation
Description
What happened
The host is a MacBook running the T3 Code desktop app with T3 Connect on, and the client is the Android app. The phone can't open a new connection to the host while the host is on a full-tunnel work VPN. The errors shown include "Your cloud sign-in changed", "Your DNS or firewall may be blocking T3 Connect" and "Could not connect relay environment". A phone session opened before the VPN came on keeps working. Turning the VPN off lets the phone connect right away. The VPN is needed on the host for work, so turning it off isn't a real option.
Diagnosis
The cause is QUIC path MTU in the managed cloudflared. It is not DNS, a firewall, or sign-in.
- T3 started
cloudflared tunnel runwhile the Mac was on its home network (MTU 1500). Each of the 4 QUIC connections probed up toquic_client_mtu = 1344(max_udp_payload = 1360). - The VPN (UniFi Identity Enterprise VPN) then became the default route. Its
utuninterface has MTU 1280. QUIC doesn't lower its MTU when that happens, so full-size packets were silently dropped. 3 of the 4 connections showedsmoothed_rtt 0and hundreds oflost_packets{reason="time_threshold"}, but/readystill reportedreadyConnections: 4and status 200. - Small exchanges still fit, so the tunnel looked healthy. Every relay
POST /api/t3-connect/mint-credentialreached the host and returned 200, and existing sessions stayed up. Anything bigger stalled until it timed out. Through the public tunnel hostname,GET /api/auth/session(230 B) answered in about 0.1s, whileGET /favicon.icoandPOST /api/auth/websocket-tickethung for over 10s. The same requests answer in under 1 ms on127.0.0.1:3773. - While the phone was failing, the host saw a mint-credential every ~25s, all 200. Only some were followed by
POST /oauth/token, and the connection never got past setup. That's why the client reports a connect/network error even though the host's traces are allSuccess. - Killing
cloudflared(T3 respawned it,ManagedEndpointRuntime.ts) fixed it straight away. The new connections probed over the VPN and settled onquic_client_mtu = 1252. Every request above then completed in about 0.1s, including the 82 KB favicon, and the phone connected with the VPN still on.
Nothing in apps/server/src/cloud/ (checked at main @ a1d9d72) reacts to the host's default route or interface changing. cloudflared is always started with tunnel --no-autoupdate --loglevel info --output default run and the default QUIC transport, and it keeps the MTU it picked on the old network for its whole life. Related symptom: #7447 (a spawned but unhealthy tunnel is reported as running), except here registration succeeded and the connections degraded afterwards.
Possible directions, for maintainers to judge: restart the managed connector when the default route or interface changes; detect connections that are registered but stalled (high loss, zero RTT) and recycle them; or let users force --protocol http2 (TCP adapts through MSS).
Steps to reproduce
- On a network with MTU 1500, start the T3 Code desktop app with T3 Connect on. Confirm the Android app can connect.
- Connect the host to a full-tunnel VPN whose interface MTU is 1280 (WireGuard-style). Confirm
curl -s http://127.0.0.1:20241/metrics | grep quic_client_mtustill shows 1344. - Force-quit the Android app and reopen it. Opening the environment fails with the errors above.
- Through the tunnel hostname,
curl https://<tunnel-host>/api/auth/sessionsucceeds quickly, whilecurl https://<tunnel-host>/favicon.icohangs. pkill -f "cloudflared tunnel", wait about 30s for T3 to respawn it, and retry.quic_client_mtuis now 1252 and the phone connects.
Version
Desktop 0.0.45 (macOS app "T3 Code (Alpha)"), Android app 1.3.0
Environment
macOS 15.7.3 (Apple silicon), managed cloudflared 2026.9.3, UniFi Identity Enterprise VPN (full tunnel, utun MTU 1280)
Evidence
# cloudflared metrics while broken (VPN on, connector started before the VPN)
quic_client_mtu{conn_index="0..3"} 1344
quic_client_max_udp_payload{conn_index="0..3"} 1360
quic_client_smoothed_rtt{conn_index="0"} 14 # conn 1..3: 0
quic_client_lost_packets{conn_index="0",reason="time_threshold"} 109
quic_client_lost_packets{conn_index="1",reason="time_threshold"} 125
quic_client_lost_packets{conn_index="2",reason="time_threshold"} 68
quic_client_lost_packets{conn_index="3",reason="time_threshold"} 231
/ready -> {"status":200,"readyConnections":4}
# through the public tunnel hostname, while broken
GET /api/auth/session 200 0.11s 230B
GET /favicon.ico 000 10.0s (timeout) # 82338B, 0.001s on 127.0.0.1
POST /api/auth/websocket-ticket 000 10.0s (timeout) # 401 in 0.0008s on 127.0.0.1
# host server.trace.ndjson while the phone was failing (all spans Success)
15:11:04 POST /api/t3-connect/mint-credential 200
15:11:17 POST /api/t3-connect/mint-credential 200
15:11:29 POST /api/t3-connect/mint-credential 200
15:11:42 POST /api/t3-connect/mint-credential 200
15:12:09 POST /api/t3-connect/mint-credential 200
...
# after killing cloudflared and T3 respawning it (VPN still on)
quic_client_mtu{conn_index="0..3"} 1252
GET /api/auth/session 200 0.08s
GET /favicon.ico 200 0.11s 82338B
GET / 200 0.09s 19493B
POST /api/auth/websocket-ticket 401 0.08s (x5)Related issues
#5744 (native clients time out "despite healthy relay tunnel" after a host restart). It may be the same failure if that host's connector started on a path with a different MTU; that report never pinned down the cause. #14264 shows the same "DNS or firewall" message, but there the cause is on the phone (iOS Connectivity Assist). Here the cause is on the host. #7447 is about a tunnel that never registers; here it registered and degraded later.
Fix applied or workaround
pkill -f "cloudflared tunnel" after connecting the VPN. T3 respawns the connector, which re-probes MTU on the new path. The fix only lasts until the network path changes again.
Filed by
Claude Code (claude-opus-5-5), following .github/triage/PLAYBOOK.md
Activity
pprg1996 commentedon Oct 15, 2026
Reproduced on macOS (arm64), desktop-managed launchd service
0.0.46-nightly.20261015.3176, cloudflared 2026.8.2, with TunnelBear 5.4.0 (WireGuard, full-tunnel,utun4MTU 1280). In this case the trigger is a VPN off→on cycle, not just joining a VPN:quic_client_mtu1252 on all 4 connections; relay fine.failed to accept QUIC stream: timeout: no recent network activity; cloudflared reconnects over Wi-Fi and settles onquic_client_mtu1344.127.0.0.1:3773answers, but every request through the public hostname times out, even small ones (/api/t3-connect/healthwith a 30 s timeout), and cloudflared logsstream … canceled by remote with error code 0./readystill reports{"status":200,"readyConnections":4}. Metrics: MTU 1344 ×4; one connection hassmoothed_rtt 0andlost_packetsrising 54 → 71 in ~2 min.cloudflared. T3 respawned it, it settled on MTU 1252 ×4, and health,/.well-known/t3/environmentand a 146 KB/favicon.icoall returned 200 in under 0.5 s. No server restart needed.It isn't deterministic: an earlier controlled run (cloudflared started on Wi-Fi at MTU 1344, then VPN on) kept working for ~60 s, including the 146 KB response. Since
/readystays green, a health probe through the public hostname (or restarting cloudflared when the default route/interface changes) seems needed to catch it.t3dotgg commentedon Oct 21, 2026
Note
🤖 Claude Opus 5.5 responding on behalf of Theo
Thanks for the report. One part of this is fixed on main in #20382. Please test on the nightly built from main on 2026-10-21, or on the next stable release. One part is still open: No route or MTU change detection was added, and fallback depends on repeated idle warnings. If that part still matters to you, please open a new issue for that part only.