Skip to content

[Bug]: T3 Connect relay rejects freshly issued credential on tunnel recovery registration (not_authorized → "Managed endpoint origin could not be confirmed") #21521

Closed as not planned

Description

@whydew

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

  1. On Windows, with T3 Code desktop (nightly), go to Settings → T3 Connect and turn T3 Connect on (or run the "Set up T3 Connect" dialog → Continue).
  2. To rule out a stale credential, I did a full reset first:
    • t3 connect logout → "Revoked the relay-side environment record. Signed out of T3 Connect locally."
    • t3 connect --headless → device approved in the browser. t3 connect status now shows Authorization: stored credential.
    • Fully quit every T3 Code process, reopened the app, signed out of and back into the T3 account in the app.
  3. Turn T3 Connect on again.

Expected behavior

The environment links to T3 Connect and the managed tunnel is registered.

Actual behavior

The toggle switches back off and shows:

This environment was removed from T3 Connect. Turn it on to link it again.
Could not configure environment relay access: Managed endpoint origin could not be confirmed.

Before the reset, the Environments list also showed "Could not load T3 Connect environments: Relay rejected the cloud session token."

The server trace shows that the relay rejects the credential it was just given:

  1. POST /api/connect/relay-config → environment.cloud.applyRelayConfig succeeds (the new relay config/credential is persisted).
  2. About 150 ms later, environment.cloud.registerManagedCloudTunnelRecovery → POST {relay}/v1/environments/{id}/tunnel/recovery is rejected:
    RelayRequestError rejection=unauthorized
    T3 Connect: Relay authentication failed: not_authorized.
    
  3. markLinkRevoked runs, registration.status !== "ready", and the server throws CloudLinkEndpointUnavailableError { reason: "origin-unconfirmed" }, which becomes a 503 to the client.

It still happens with a freshly issued CLI authorization and a restarted server process, so it doesn't look like a stale local credential. The relay seems to refuse tunnel-recovery registration for a credential issued moments earlier. Possibly related: #8112 (credential stays invalid after a clean relink).

The error message also points users toward a fix that doesn't help here. "Managed endpoint origin could not be confirmed" hides the underlying not_authorized.

Impact

Blocks work completely (for T3 Connect / remote access; local use is unaffected)

Version or commit

0.1.1-nightly.20261018.3335

Environment

Windows 11 Pro (10.0.26200), x64, T3 Code (Nightly) desktop, Electron 44.4.5. Relay https://relay.t3.codes, cloudflared 2026.10.0 (managed install). serverExposureMode: network-accessible (server binds 0.0.0.0:3773).

Logs or stack traces

Trace IDs (all not_authorized on tunnel recovery registration):

  • b8a5dd77a0656969eb4e97d4c0464dcc — after a full logout, relogin and app restart
  • a89c68718e8e11c5ae5a25831d315609 — after relogin, before the app restart
  • 254b2dd25b3163e223104caadc9d629f — original failure
CloudLinkEndpointUnavailableError: Managed endpoint origin could not be confirmed.
    at environment.cloud.relayConfig (server.asar/apps/server/dist/binCli-BF0nlet2.mjs:329579:138)

The environment ID is available privately to maintainers if needed.

Activity

  1. juliusmarminge commented on Oct 19, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    This isn't a duplicate of #8112 (a client failing to connect) or #19034 (linking itself failing). Here the link succeeds and only the next step fails, and on main that pattern points to the host clock, so we need one detail before treating it as a relay bug.

    The tunnel recovery registration signs a proof that expires 60 seconds after it is issued, and the relay allows 60 more seconds of drift. The link proof that succeeded just before it is valid for 5 minutes. A host clock running about 2 to 6 minutes behind would pass linking and then get exactly this not_authorized, every time, including after a logout and relogin. That is the scenario #19501 covers.

    Could you share:

    1. Your clock offset: the output of w32tm /stripchart /computer:time.windows.com /samples:5 /dataonly, or your clock compared with time.is.
    2. Whether turning T3 Connect on works after a time sync, without logging out first.

    Please keep the environment ID out of this thread.

    You're right that "Managed endpoint origin could not be confirmed" replaces the relay's not_authorized on this path.

  2. added
    needs more infoInitial triage showed no bug. Awaiting more info
    via-triageFiled through npx t3 triage
    and removed
    needs more infoInitial triage showed no bug. Awaiting more info
    on Oct 19, 2026
  3. juliusmarminge commented on Nov 12, 2026

    @juliusmarminge
    Member

    I tried to reproduce this on the current build and could not.

    Commit 9f1e97d (origin/main). A real end-to-end run was not possible: T3 Connect and the relay are not available on the VMs. I reproduced the server-side behaviour in CloudLink's lifecycle test harness: applyRelayConfig with a cloudflare_tunnel endpointRuntime, where the relay's POST /v1/environments/env_123/tunnel/recovery answers 401 {code: auth_invalid, reason: not_authorized}. Observed: applyRelayConfig fails with CloudLinkEndpointUnavailableError, message "Managed endpoint origin could not be confirmed.", and the link is marked revoked. This matches the reporter's trace (registerManagedCloudTunnelRecovery gets not_authorized, markLinkRevoked runs, origin-unconfirmed, 503). The test 'reports the relay's refusal when linking cannot register its tunnel' in apps/server/src/cloud/CloudLink.lifecycle.test.ts fails on main (1 failed, 34 passed). The relay's rejection of a fresh credential itself was not reproduced. The maintainer's comment attributes it to host clock skew (the recovery proof expires 60s after issue, plus 60s of drift), and the reporter has not yet given their clock offset.

    Closing as not planned. If it still happens for you, reply with the exact steps and the version you are on and it will be looked at again.

  4. FarazRazi commented on Nov 14, 2026

    @FarazRazi

    Reproduced on 0.1.10-nightly.20261114.4682 (Windows 11 Pro 10.0.26200 x64, T3 Code Nightly desktop, Electron 44.10.1). The cause is confirmed as host clock skew, as suggested above.

    Clock offset: w32tm /stripchart /computer:time.windows.com /samples:1 /dataonly → +51605.1169520s (host about 14 h 20 m behind). Confirmed by the Date headers from google.com, cloudflare.com and api.github.com. The machine is domain-joined and its domain time source was unreachable, so Windows never corrected the clock.

    Symptoms, same as the original report:

    • Turning T3 Connect on: "This environment was removed from T3 Connect" / "Could not configure environment relay access: Managed endpoint origin could not be confirmed." The trace shows environment.cloud.relayConfig failing with CloudLinkEndpointUnavailableError (origin-unconfirmed) about 2 s after the link proof succeeds. That matches the registerManagedCloudTunnelRecovery → 401 → markLinkRevoked path.
    • Connecting from this desktop to a healthy remote host over T3 Connect: "T3 Connect did not accept this device's sign-in" / "Relay rejected the cloud session token." (trace d2b002a100a1bd74dc6530f3a90ac6d8). The remote host is on the same version, and its t3 connect status shows the tunnel connected.
    • Signing out and back in, plus restarting, doesn't help.

    Server trace IDs for the failed links: f2907175f9a0950641f3d395cd1e295f (relayConfig), 2ddf28bac5e0f99ab51ff4169c280ddb, 02e28cd21937f46a88007353496c513c.

    Still a product gap: nothing in the UI points at the clock. A clock-related 401 is shown as "removed from T3 Connect" and "origin could not be confirmed", and invalid_bearer has no clock hint (only the DPoP errors do). The link also stays marked revoked after the clock is fixed. #19501 addressed all of this but was closed without merging, and main hasn't changed these paths since this nightly.

    I'll follow up on whether turning T3 Connect on works after a time sync without signing out.

    Prepared by Claude Code (Claude Opus 5.5) via t3 triage.

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

    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