Skip to content

Deregistered T3 Connect environment keeps failing with "no active link" and the server never notices or relinks #19069

Closed

Description

@StivenKN

What happened

The user accidentally deregistered their Mac from T3 Connect (Account → T3 Connect → Deregister). Two days later, the environment still appeared in Settings → Connections on nightly.app.t3.codes but would not connect:

Connection failed. Reason: Relay has no active link for this environment. The environment server may not have re-established its link yet.

The message suggests the error is transient, but the server never re-established the link and the UI offered no way to repair it. The T3 Connect toggle on the environment still showed as on.

Diagnosis

Deregistering removes the environment link and its credential on the relay. The environment server never learns about it:

  • Local state still says linked. t3 connect status --json reported "desired": true, "authenticated": true, "linked": true with a relayUrl set.
  • On every boot, the server respawns cloudflared from the stored runtime config, using the old tunnel. It then calls registerManagedTunnelRecovery (apps/server/src/cloud/CloudLink.ts), and the relay rejects the environment credential with not_authorized (layerEnvironmentAuth in infra/relay/src/http/Api.ts). In apps/server/src/server.ts that failure becomes Effect.logWarning("Failed to register T3 Connect managed tunnel recovery") and { status: "unavailable" }. Nothing clears the local link or relinks.
  • Agent activity publishing fails with the same RelayAuthInvalidError: not_authorized (publishThreadUnsafe).
  • Clients get RelayEnvironmentConnectNotAuthorizedError with reason environment_link_not_found (EnvironmentConnector.status/connect, infra/relay/src/environments/EnvironmentConnector.ts). packages/client-runtime/src/relay/errorPresentation.ts renders it as "may not have re-established its link yet", which can never become true in this state.

The traces showed this loop on every boot over the retained window (about 2 days of rotated server.trace.ndjson).

Expected: when the relay rejects the environment credential with not_authorized (or the link is not found), the server should treat the link as revoked. It should either clear the local link state and surface "this environment was removed from T3 Connect, relink?", or relink automatically when the link is still desired and the CLI/user token is valid. The client message for environment_link_not_found should also point at relinking instead of waiting.

Steps to reproduce

  1. Link a desktop or t3 serve environment with T3 Connect (managed tunnel) and confirm it connects from another client.
  2. In Account → T3 Connect, click Deregister on that environment.
  3. Restart the environment server (or leave it running).
  4. From another client, try to connect to the environment. You get "Relay has no active link for this environment…" indefinitely.
  5. On the environment host, t3 connect status still reports linked: true. Each boot logs WARN Failed to register T3 Connect managed tunnel recovery with not_authorized.

Version

0.0.46-nightly.20261013.3042 (desktop app and CLI runtime)

Environment

macOS 27.0 (Darwin 27.0.0, arm64), Node v24.21.0, T3 Code (Nightly) desktop app plus the launchd background service, both on the same ~/.t3; cloudflared 2026.10.0 (managed)

Evidence

# server.trace.ndjson, environment.cloud.registerManagedCloudTunnelRecovery, on every boot (00:00, 08:20 service, 08:28 desktop)
RelayRequestError: T3 Connect: Relay authentication failed: not_authorized. Run `t3 connect login` to check this machine's authorization. If the stored credential was revoked, sign out with `t3 connect logout`, then run `t3 connect ...

# boot-service.log
WARN Failed to register T3 Connect managed tunnel recovery { cause: { _id: 'Cause', failures: [ [Object] ] } }

# publishThreadUnsafe
RelayAuthInvalidError: Relay authentication failed: not_authorized

# t3 connect status --json (before fix)
{ "desired": true, "authenticated": true, "linked": true, "relayUrl": "https://relay.t3.codes", ... }

# Client (Settings → Connections)
Connection failed. Reason: Relay has no active link for this environment. The environment server may not have re-established its link yet.

Related issues

#11899 is the same class of local and relay state drift, where the UI can't detect or repair a link that drifted to publish-only. This report is a different drift: the relay link was removed entirely and the credential revoked, so the fix point differs (the not_authorized handling on recovery registration and the environment_link_not_found message). #6568 is related but is about endpoint_provider_not_managed.

Fix applied or workaround

  1. Quit the app, then ran t3 connect unlink followed by t3 connect link, and reopened the app. The server provisioned a new tunnel, recovery registration succeeded, and remote clients connected again after about 2 minutes of hostname propagation.
  2. Side note: t3 connect unlink on the already-deregistered environment cleared local state but printed Relay internal error: upstream_unavailable (trace ID ca177a499017df7b552deaa1dac1c3e4) from DELETE /v1/client/environment-links/:id. A missing link should probably return ok: false ("not linked") rather than an internal error.
  3. Unrelated to the bug: also uninstalled the launchd background service, because the user only wants the desktop app. Before that, both the service and the desktop backend ran their own cloudflared connector for the same tunnel from the same ~/.t3.

Filed by

Claude Code (claude-opus-5-5) via t3 triage

Activity

  1. juliusmarminge commented on Oct 13, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Confirmed on main: this is a bug. When the relay revokes the link, the server only logs a warning and never treats it as revoked.

    • In apps/server/src/server.ts (~L1002), any failure from registerManagedTunnelRecovery, including not_authorized, is caught, logged as Failed to register T3 Connect managed tunnel recovery, and turned into { status: "unavailable" }. Local link state is never cleared, and nothing prompts a relink, so t3 connect status keeps reporting linked: true.
    • In packages/client-runtime/src/relay/errorPresentation.ts (L43–44), environment_link_not_found always renders as "may not have re-established its link yet." That message implies the problem is temporary, which isn't true once the link has been deregistered.

    Workaround: run t3 connect unlink on the host, then t3 connect link.

    This isn't a duplicate. #11899 covers drift to publish-only, and #6568 covers endpoint_provider_not_managed. The upstream_unavailable 500 you got when unlinking an already-deregistered link belongs in #17043, which tracks unlink failing when the relay can't release the link.

    Suggested fix: when recovery returns not_authorized or environment_link_not_found, mark the link revoked in local state and show "removed from T3 Connect, relink?". Also change the client message for environment_link_not_found to point to relinking instead of waiting.

  2. added
    acceptedfeature request accepted
    bugSomething is broken or behaving incorrectly.
    via-triageFiled through npx t3 triage
    on Oct 13, 2026
  3. added 3 commits that reference this issue on Oct 14, 2026
    ae0158b
    7f1da0c
    e98968e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    acceptedfeature request acceptedbugSomething is broken or behaving incorrectly.via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions