[BUG] Claude-spawned child shells on Windows can't complete new outbound TLS handshakes to non-Anthropic endpoints (breaks Perforce)
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Summary
On Windows, processes spawned as descendants of claude.exe (the tool-call PowerShell shell, and its children like p4.exe) cannot complete new outbound TLS handshakes to non-Anthropic endpoints. TCP succeeds, the TLS handshake
stalls (no ServerHello arrives), the call eventually times out. The exact same call from a non-Claude terminal on the same machine — or from a process spawned outside Claude's process tree via WMI — succeeds instantly.
For teams using Perforce-controlled repos (game dev, hardware, large monorepos), this is a hard blocker: Claude Code on Windows can read files but can't run p4 edit to check them out, so any code change against a checked-in
file fails until the user manually checks it out from a different terminal.
Note: CLAUDE_CODE_PERFORCE_MODE (added in 2.1.98) helps the read-only-file half of the workflow by making Edit/Write/NotebookEdit fail fast with a p4 edit hint, but it doesn't address this issue — the suggested p4 edit
command itself still hangs at TLS handshake from inside the Claude shell.
Environment
- OS: Windows 11 Pro 10.0.26200
- Shell: PowerShell 7.6.1 (Core)
- Claude Code: 2.1.140
- Process tree at failure: pwsh.exe (tool call) ← claude.exe ← powershell.exe (Rider terminal integration) ← rider64.exe
- Other AV on box: Norton Security — fully ruled out (disabling all Norton components didn't change the symptom; p4 info works fine from non-Claude terminals with Norton at its normal settings).
Reproducer
From inside a Claude Code shell on Windows:
p4 -p ssl:<PERFORCE_HOST>:1666 info
Returns after ~30s:
Perforce client error:
SSL connect to ssl:<PERFORCE_HOST>:1666 timed out.
The same command from a separately-opened terminal (Win+R → pwsh) returns the server info immediately.
Diagnostic findings
- TCP three-way handshake to the depot's IP succeeds from inside the Claude shell (Test-NetConnection reports TcpTestSucceeded: True).
- TLS handshake never receives a ServerHello — confirmed both via p4.exe (OpenSSL) and via bare .NET SslStream invoked from PowerShell 7 (modern .NET 8 SSL stack). Same symptom for both, same timeout, no MITM cert ever
delivered.
- Bare .NET SslStream to google.com:443 from the same shell works fine — so this is destination-specific, not "all TLS broken."
- IsProcessInJob(GetCurrentProcess(), NULL, &result) on the Claude tool-call shell returns True — Claude is placing its descendants in a Windows Job Object.
- Spawning p4.exe via Invoke-CimMethod Win32_Process Create (so the new process is parented by svchost, escaping Claude's process tree) succeeds instantly from inside a Claude shell — same machine, same network, same p4.exe
binary, same user identity. This is what nailed down the cause.
- JetBrains Rider's PerforcePlugin.exe (P4Java, JVM SSL stack) makes new handshakes to the same depot at the same time and they succeed — confirming the depot and the network path are fine; only Claude descendants are
blocked.
Probable cause
A WFP / Winsock filter (or similar network-policy mechanism) is attached to the Windows Job Object that claude.exe places its children in, silently dropping outbound TLS handshakes from job members to non-allowlisted
endpoints. The Anthropic API endpoint is presumably on the allowlist since Claude Code itself talks to the API fine.
This is not a per-version regression in the binary — the same claude.exe 2.1.140 build worked for the user with Perforce in one workspace a few hours before failing in another. Some state or configuration drives the
enablement.
Workaround
Route p4 commands through WMI to spawn them outside Claude's process tree:
$outFile = "C:\Users\<USERNAME>\\AppData\Local\Temp\claude-p4-out.txt"
if(Test-Path $outFile) { Remove-Item $outFile -Force }
$cmd = "cmd /c ""C:\Program Files\Perforce\p4.exe" -c <CLIENT> <ARGS> > "$outFile" 2>&1""
$result = Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments @{
CommandLine = $cmd
CurrentDirectory = "<WORKSPACE_ROOT>"
}
$deadline = (Get-Date).AddSeconds(30)
while((Get-Date) -lt $deadline) {
if(-not (Get-Process -Id $result.ProcessId -ErrorAction SilentlyContinue)) { break }
Start-Sleep -Milliseconds 300
}
Get-Content $outFile
This works reliably but is a deliberate sandbox bypass — the responsibility is now on the user to authorize Claude to use it.
NOTE this was written by claude after helping it debug
What Should Happen?
Suggested fix
One of:
- Allowlist Perforce traffic in the Job-Object-bound network policy by default. Perforce ops happen constantly during normal editing flow on a Perforce-controlled repo; gating them silently isn't workable. A simple p4.exe /
p4vc.exe / p4broker.exe exemption (similar in spirit to how CLAUDE_CODE_PERFORCE_MODE already specifically recognizes Perforce-flavored read-only failures) would cover the common case.
- Provide a documented user-facing allowlist for outbound TLS targets — e.g., a networkAllowlist field in settings.json listing host:port pairs the user trusts. Useful beyond Perforce (private registries, internal git over
SSL, corporate Jira/Confluence APIs called from custom hooks/scripts, etc.).
- Surface the containment in claude doctor / --version so users can see what their session can and can't reach. We spent hours chasing Norton red herrings before tracing it to Claude's Job Object — IsProcessInJob returning
True plus a list of blocked outbound destinations would have saved that time. Documenting the containment in CLAUDE_CODE_PERFORCE_MODE's reference page would also help, since users currently set that flag and reasonably
assume it will unblock the matching p4 edit call — but the network containment then prevents the very command the hint tells them to run.
NOTE this was written by claude after helping it debug
Error Messages/Logs
Perforce client error:
SSL connect to ssl:<PERFORCE_HOST>:1666 timed out.
Steps to Reproduce
Reproducer
From inside a Claude Code shell on Windows:
p4 -p ssl:<PERFORCE_HOST>:1666 info
Returns after ~30s:
Perforce client error:
SSL connect to ssl:<PERFORCE_HOST>:1666 timed out.
The same command from a separately-opened terminal (Win+R → pwsh) returns the server info immediately.
Claude Model
Opus
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.140
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
PowerShell
Additional Information
It was working until I opened a different project with claude (both Rider), but then it stopped working for both. Claude assured me that opening a different project didn't change anything. It compared the project/rider/perforce settings for both and said there were no differences other than workspace name
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗