pingdotgg / pingdotgg/t3code

[Bug]: T3 Connect reports "relay offline" when the server binds a non-loopback host

Open
#4,915 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

bug needs-triage
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 on 0.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 update regenerates 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), relay https://relay.t3.codes

  • Tunnel: id 087c60cb-8a6a-4ce6-9863-3c6bcdc18f8c,
    name t3coderelay-managedendpoint-prod-f2762562ff52ab75,
    public endpoint https://prod-f2762562ff52ab75.t3coderelay.com

Reproduction

  1. Install the background service; set T3CODE_HOST=<LAN_IP> (drop-in or env). Server binds
    <LAN_IP>:3773 only — confirmed via ss -tlnp.
  2. t3 connect link, complete browser authorization.
  3. 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.
  4. Access the machine through the relay (or wait for the relay's own
    /api/t3-connect/mint-credential call).

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)

  1. Derive the ingress origin from the effective bind host when reconciling the link, or
  2. Always bind an additional loopback listener when Connect is enabled and the configured
    host doesn't cover 127.0.0.1 — with a startup log line saying so, or at minimum
  3. Surface the failure: connect status (and/or the serve-side reconciler) should probe the
    ingress origin and report "relay client cannot reach origin http://127.0.0.1:3773 — server
    is bound to 192.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.
  4. 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 link authorized; 18:30 service restart, tunnel registers, status all-green
  • 19:02 stray service update foreground server on loopback briefly makes relay traffic work
    (masking the bug), killed at 19:07
  • 20:33–20:35 continuous connection refused transport 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.