Skip to content

[Bug]: Windows T3 Connect relay client install fails with EBUSY while staging cloudflared #16945

Description

@BramTops

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

packages/contracts or packages/shared

Steps to reproduce

  1. On Windows 11, run npx t3 connect.
  2. Accept the prompt to download and install the required relay client.
  3. Let the download, verification, and executable validation complete.

This failed on three separate Windows 11 machines, including personal and corporate networks.

Expected behavior

The relay client installs and T3 Connect setup completes.

Actual behavior

Activation fails with RelayClientInstallError: Could not stage the relay client. The underlying error is EBUSY while renaming the temporary cloudflared.exe to a staging filename. Renaming the file manually later succeeds.

Impact

Major degradation or frequent failure

Version or commit

T3 CLI 0.0.45; managed relay client 2026.5.2

Environment

Windows 11, three separate machines.

Logs or stack traces

From `npx t3 connect`:
RelayClientInstallError: Could not stage the relay client.
    EBUSY: resource busy or locked, rename
    'C:\Users\XXX\.t3\tools\cloudflared\2026.5.2\win32-x64\.install-GT4GBS\cloudflared.exe'
    ->
    'C:\Users\XXX\.t3\tools\cloudflared\2026.5.2\win32-x64\cloudflared.exe.<uuid>.tmp'

Relevant ProcMon log below. They show a `SHARING VIOLATION` on T3's delete-access open of the temporary executable shortly after it was run for validation. The rows do not establish which process held the conflicting handle.

"Time of Day","Process Name","PID","Operation","Path","Result","Detail"
"21:56:05.8210146","MsMpEng.exe","5524","CreateFileMapping","C:\Users\XXX\.t3\tools\cloudflared\2026.5.2\win32-x64\.install-GT4GBS\cloudflared.exe","FILE LOCKED WITH ONLY READERS","SyncType: SyncTypeCreateSection, PageProtection: PAGE_READONLY"
"21:56:05.8568995","MsMpEng.exe","5524","CreateFileMapping","C:\Users\XXX\.t3\tools\cloudflared\2026.5.2\win32-x64\.install-GT4GBS\cloudflared.exe","FILE LOCKED WITH ONLY READERS","SyncType: SyncTypeCreateSection, PageProtection: PAGE_READONLY"
"21:56:05.8951741","t3.exe","25356","CreateFileMapping","C:\Users\XXX\.t3\tools\cloudflared\2026.5.2\win32-x64\.install-GT4GBS\cloudflared.exe","FILE LOCKED WITH ONLY READERS","SyncType: SyncTypeCreateSection, PageProtection: PAGE_EXECUTE"
"21:56:06.0581246","cloudflared.exe","10168","ReadFile","C:\Users\XXX\.t3\tools\cloudflared\2026.5.2\win32-x64\.install-GT4GBS\cloudflared.exe","END OF FILE","Offset: 54,116,816, Length: 32,768"
"21:56:06.0797153","t3.exe","25356","CreateFile","C:\Users\XXX\.t3\tools\cloudflared\2026.5.2\win32-x64\.install-GT4GBS\cloudflared.exe","SHARING VIOLATION","Desired Access: Read Attributes, Delete, Synchronize, Disposition: Open, Options: Synchronous IO Non-Alert, Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a"
"21:56:06.0830028","t3.exe","25356","CreateFile","C:\Users\XXX\.t3\tools\cloudflared\2026.5.2\win32-x64\.install-GT4GBS\cloudflared.exe","SHARING VIOLATION","Desired Access: Read Attributes, Delete, Synchronize, Disposition: Open, Options: Synchronous IO Non-Alert, Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a"

Screenshots, recordings, or supporting files

No response

Workaround

No known workaround. A later manual rename succeeds, but rerunning npx t3 connect fails again.

Activity

  1. added
    bugSomething is broken or behaving incorrectly.
    needs-triageIssue needs maintainer review and initial categorization.
    on Oct 7, 2026
  2. juliusmarminge commented on Oct 7, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Thanks for the ProcMon capture. Triage: confirmed on current main. The installer renames the freshly executed cloudflared.exe once, right after the validation run exits, and nothing retries a transient Windows lock.

    Mechanism (packages/shared/src/relayClient.ts on main):

    1. The download is checksummed in memory, then written to .install-XXXX\cloudflared.exe inside a scoped temp directory (L397-L409).
    2. That same file is run as cloudflared version to validate it (L422-L425). runCommand waits only for the exit code (L263-L278).
    3. The very next step renames that executable to cloudflared.exe.<uuid>.tmp, with a single fileSystem.rename call. Any failure becomes write_failed / "Could not stage the relay client." (L427-L431). The second rename into place has the same single-shot shape (L432-L437).

    So any process still holding the just-run image without delete sharing makes the install fail outright. That matches the SHARING VIOLATION on T3's delete-access open in your log. Your log doesn't show which process held the handle; Defender (MsMpEng.exe) mapping the file just before is a plausible candidate, but it isn't proven. The only retry loop in this installer is for the install lock file (L328-L351), not for the renames. The repo already handles this Windows behaviour elsewhere: the CLI archive smoke test retries cleanup because "Windows can keep t3.exe locked (EBUSY) for a moment" after it exits (scripts/smoke-cli-archive.ts L78-L88).

    This code is unchanged in behaviour since 0.0.45. The only diffs between v0.0.45 and main in this file are Effect import renames and a lint-only catchTags change.

    Fix direction

    • Retry both renames on Windows when they fail with EBUSY/EPERM/EACCES, using a short bounded backoff. The smoke script's Effect.retry with Schedule.spaced is the existing pattern.
    • Or avoid renaming an image that just ran: validate a separate copy, and stage and activate the copy that was never executed.

    Workaround

    t3 connect skips the installer whenever a file already exists at the managed path (resolve, L236-L243; apps/server/src/cli/connect.ts L247-L249). Until this is fixed, you can install the binary by hand:

    1. Download cloudflared-windows-amd64.exe 2026.5.2.
    2. Check that its SHA-256 is 20b9638f685333d623798e733effbad2487093f15ba592f6c7752360ff3b7ab7 (the pinned checksum).
    3. Save it as %USERPROFILE%\.t3\tools\cloudflared\2026.5.2\win32-x64\cloudflared.exe (that's under the default T3 home; use your own base directory instead if you pass --base-dir).
    4. Rerun npx t3 connect.

    You can also point T3CODE_CLOUDFLARED_PATH at that file.

    Related

  3. added
    via-triageFiled through npx t3 triage
    and removed
    needs-triageIssue needs maintainer review and initial categorization.
    on Oct 7, 2026
  4. steverosky commented on Oct 8, 2026

    @steverosky

    Reproduced on Windows 11 Pro with T3 Code (Nightly) desktop 0.0.46-nightly.20261008.2801, using the Settings → Connections toggle rather than npx t3 connect. The managed relay client is 2026.5.2.

    • 11 consecutive attempts, from 01:48 to 03:07 local time, each left a complete .install-*\cloudflared.exe (same SHA-256, valid Cloudflare Authenticode signature). Each attempt then failed with EBUSY: resource busy or locked, rename '...\.install-r1b3um\cloudflared.exe' -> '...\win32-x64\cloudflared.exe.<uuid>.tmp'.
    • Windows Defender real-time protection is the only antivirus. Controlled folder access is off.
    • Manual recovery: Moving one staged copy to win32-x64\cloudflared.exe works. t3 connect status then reports Relay client: available via managed install.
    • Preventing a repeat: Adding a Defender exclusion for %USERPROFILE%\.t3\tools stops it from recurring.

    The Codex CLI 0.161.0 daemon installer failed the same way on this machine. Copying a freshly written binary into its staging folder returned "Access is denied", which also points to Defender holding a transient lock. A short retry on the rename, as proposed above, would cover this case.

  5. ScottN-PV commented on Oct 8, 2026

    @ScottN-PV
    Contributor

    Thanks, this fills two gaps in the report. Defender real-time protection is the lock holder, since an exclusion for %USERPROFILE%\.t3\tools stops the failure, and the desktop Settings → Connections toggle hits the same staging rename as npx t3 connect.

    #16998 covers this case: on Windows it retries both renames on EBUSY/EPERM/EACCES for about 10 seconds before reporting the existing error. Its verification held the lock with a PowerShell script, so it has not been run against Defender. A run of the fix on a Defender-only machine would show whether that window is long enough. When a lock outlasts it, the install still fails with the same message and leaves the staged copy under .install-*, as it does today.

    Written by Claude Fable 5.1 on behalf of ScottN-PV.

  6. added a commit that references this issue on Oct 8, 2026
    712926a
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

    bugSomething 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