[Bug]: T3 Connect reports "relay offline" when the server binds a non-loopback host
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 23k
- Forks
- 5.9k
- Avg merge
- 11h 14m
- Merged PRs (30d)
- 357
Description
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/server
Steps to reproduce
Handoff: T3 Connect reports "relay offline" when the server binds a non-loopback host
TL;DR
The managed relay tunnel always delivers traffic to http://127.0.0.1:3773, but T3CODE_HOST
lets the server bind a single non-loopback address. With T3CODE_HOST=192.168.0.80 (the
documented way to make phones/tablets reach the server on the LAN), nothing listens on loopback,
every relayed request dies with connection refused, and the relay marks the machine offline —
while t3 connect status reports everything healthy. Silent, total Connect outage from a
supported configuration.
Environment
-
t3
0.0.31(also reproduced on0.0.29), installed runtime under~/.t3/runtime/versions/,
Node v24.18.0, Ubuntu (kernel 7.0.0-28-generic) -
Running as a systemd user service (
t3code.service),ExecStart … bin.mjs serve -
Host override via drop-in (per the guidance that
t3 service updateregenerates the unit):# ~/.config/systemd/user/t3code.service.d/host.conf [Service] Environment=T3CODE_HOST=192.168.0.80 -
T3 Connect: full managed tunnel, cloudflared
2026.5.2(managed install), authorized via
connect link(Clerk), relayhttps://relay.t3.codes -
Tunnel: id
087c60cb-8a6a-4ce6-9863-3c6bcdc18f8c,
namet3coderelay-managedendpoint-prod-f2762562ff52ab75,
public endpointhttps://prod-f2762562ff52ab75.t3coderelay.com
Reproduction
- Install the background service; set
T3CODE_HOST=<LAN_IP>(drop-in or env). Server binds
<LAN_IP>:3773only — confirmed viass -tlnp. t3 connect link, complete browser authorization.- Restart the service so the link reconciles. Log shows the tunnel come up:
Relay client tunnel connection registered× 4 (QUIC),T3 Connect desired link reconciled on startup. - Access the machine through the relay (or wait for the relay's own
/api/t3-connect/mint-credentialcall).
Expected: relayed traffic reaches the server.
Actual: the user-facing client reports the relay/machine offline. boot-service.log fills
with (every retry, indefinitely):
WARN Relay client reported a transport warning
output: '… ERR Request failed error="Unable to reach the origin service. The service may be
down or it may not be responding to traffic from cloudflared: dial tcp 127.0.0.1:3773:
connect: connection refused" connIndex=0
dest=https://prod-f2762562ff52ab75.t3coderelay.com/api/t3-connect/mint-credential
event=0 type=http' # originService=http://127.0.0.1:3773, ingressRule=0
Meanwhile t3 connect status shows no problem at all:
Exposure: enabled
Authorization: stored credential
Environment link: provisioned
Relay: https://relay.t3.codes
Relay client: available via managed install (cloudflared 2026.5.2)
Root cause
The tunnel's ingress origin is fixed at http://127.0.0.1:3773 (remotely-managed config for the
managed endpoint, judging by the ingressRule=0 origin in the cloudflared output), independent of
the host the server actually binds. serve honors T3CODE_HOST/--host for its single listener,
so any non-loopback bind orphans the tunnel.
Confirmed by the fix: changing only T3CODE_HOST to 0.0.0.0 (bind all interfaces) and
restarting immediately stopped the transport warnings; the public endpoint then returned 200
end-to-end. Nothing else was touched.
Workaround (verified)
[Service]
Environment=T3CODE_HOST=0.0.0.0
daemon-reload + restart. Loopback serves the tunnel, the LAN IP keeps serving local devices.
Verified: curl http://127.0.0.1:3773/ → 200, curl http://192.168.0.80:3773/ → 200,
curl https://prod-f2762562ff52ab75.t3coderelay.com/ → 200, zero transport warnings since.
Suggested fixes (any one resolves it; first two are complementary)
- Derive the ingress origin from the effective bind host when reconciling the link, or
- Always bind an additional loopback listener when Connect is enabled and the configured
host doesn't cover127.0.0.1— with a startup log line saying so, or at minimum - Surface the failure:
connect status(and/or the serve-side reconciler) should probe the
ingress origin and report "relay client cannot reach originhttp://127.0.0.1:3773— server
is bound to192.168.0.80" instead of showing all-green while the relay retries forever. The
transport warnings are already parsed by the server (they appear as structured WARNs), so the
signal exists. - Docs: the LAN-exposure guidance (
T3CODE_HOST=<LAN_IP>) and T3 Connect setup
(docs/cloud/t3-connect-clerk.md) should cross-reference this constraint until fixed.
Related bug observed while upgrading (separate report if useful)
npx t3@latest service update (resolved to 0.0.31) did not update the installed service. Instead
it booted a full foreground server in-process: ran migrations, bound 127.0.0.1:3773,
spawned its own cloudflared (stealing the managed tunnel from the running service), and printed a
live pairing URL to stdout — then ran until externally killed. ~/.t3/runtime/versions/ and the
unit's ExecStart were untouched. Looks like the service update subcommand falls through to
default serve/start behavior under npx.
Timeline (2026-07-29, PT)
- 18:28
connect linkauthorized; 18:30 service restart, tunnel registers, status all-green - 19:02 stray
service updateforeground server on loopback briefly makes relay traffic work
(masking the bug), killed at 19:07 - 20:33–20:35 continuous
connection refusedtransport warnings while user sees "relay offline" - 20:35
T3CODE_HOST=0.0.0.0+ restart → tunnel healthy, endpoint 200, warnings stop
Expected behavior
this is expected, error could be slightly more verbose but ai can detect and fix quickly
Actual behavior
can't connect using t3 connect, need to fix settings on server
Impact
Minor bug or occasional failure
Version or commit
nightly (.31)
Environment
web ui(all clients trying to use t3 connect)
Logs or stack traces
Screenshots, recordings, or supporting files
No response
Workaround
easily fixed by claude, doc included
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in apps/server by tracing serve's T3CODE_HOST/--host handling into the T3 Connect link reconciler and relay origin configuration. Reproduce with a non-loopback bind, then verify that relay traffic reaches the server and that connect status reflects the actual origin health. The documented workaround and docs/cloud/t3-connect-clerk.md provide the current expected behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend, cloud, networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100