The immediate diagnosis: why agent runs fail where browsers succeed
When claude.ai loads in a browser but Claude Code halts with ECONNRESET, Cursor drops with "Connection reset by peer", or claude doctor fails with HTTP 403 to api.anthropic.com, the issue is network transport.
AI coding agents maintain long-lived Server-Sent Events (SSE) and HTTP/2 streams across multi-minute tool runs. Commercial VPNs break these connections via 30–60s NAT idle timeouts, silent TCP RST injection, Node.js proxy quirks, and Cloudflare edge blocks against datacenter ASNs.
Below is the network breakdown for agent drops, an actionable diagnostic runbook, and the configuration for a stable path. For context on IP reputation across AI infrastructure, see our pillar on why standard VPNs get AI accounts flagged.
NAT idle timeouts and silent TCP RST on streaming responses (SSE/HTTP/2)
The most common agent failure is a mid-response drop (ECONNRESET, ETIMEDOUT, or stream closed mid-response) during thinking phases or tool execution:
[Client: Claude Code / Cursor] [VPN Gateway / NAT] [Anthropic / Cursor Edge]
| | |
|========= Active SSE Stream (Tokens) =======>|========================================>|
| | |
|-- Local Tool Execution (socket idle 45s) ---| |
| |-- NAT Entry Purged (Idle Timeout) ------|
| | (No FIN sent to either peer) |
| | |
|<======== Server sends next chunk ============| |
| |<--- Drops packet / Injects TCP RST -----|
|xxxxxxxxxxxx ECONNRESET / Socket Closed xxxxxx| |Network breakdown:
- Persistent SSE stream: The client opens an HTTP/2 or chunked TLS stream for Server-Sent Events.
- The quiet stretch: During tool execution (grep, tests, linting), the upstream socket stays idle for 30–90 seconds.
- NAT state eviction: Middleboxes enforce 30–60s idle timeouts. With no packets moving, NAT entries are purged without sending a TCP
FIN. - TCP RST injection: When transmission resumes, the middlebox drops unmapped packets and returns a TCP
RST. - Runtime crash: The client receives the RST and halts with
ECONNRESET.
Short HTTP asset fetches in browsers never hit this; agent runs require persistent transport.
Cloudflare edge 403 blocks on api.anthropic.com
Another frequent failure is an immediate HTTP 403 Forbidden before token generation:
Error: Request failed with status code 403
Cloudflare Ray ID: 89ab34cdef123456
API Connection Error: 403 Forbidden (api.anthropic.com)Running claude doctor confirms the API check fails while auth passes. This block triggers at Cloudflare's edge WAF:
- Datacenter ASN penalties: Commercial VPNs egress through hosting providers (M247, DataCamp, OVH, Hetzner) tagged as
hostingrather thanisp. - IP fraud score threshold: Shared VPN exit IPs accumulate abuse flags. High fraud scores trigger unconditional TLS termination.
- JA4 TLS fingerprinting: Node.js clients produce distinct TLS Client Hello signatures. Non-browser JA4 fingerprints from datacenter ASNs trigger bot defenses.
Environment variable inheritance and SOCKS5 vs HTTP proxy quirks in Node.js
Developers using local SOCKS5 proxies often find curl works while Claude Code or Cursor fails.
SOCKS5 blind spots in Node.js
Claude Code runs on Node.js. Node's HTTP clients (undici, native fetch, https) do not route SOCKS5 without wrapper libraries (socks-proxy-agent). While browsers support SOCKS transparently, Node CLI tools require an HTTP CONNECT proxy.
Inconsistent proxy variable resolution
CLI tools and IDEs resolve proxy variables with conflicting priorities:
- Some libraries check only lowercase
https_proxy; others require uppercaseHTTPS_PROXY. - Internal API wrappers often ignore
ALL_PROXY. - Setting an HTTPS target in
HTTP_PROXYwithoutHTTPS_PROXYbreaks TLS negotiation.
# SOCKS proxies often break Node CLI tools:
export ALL_PROXY="socks5://127.0.0.1:1080" # Often ignored by Node fetch
# Standard HTTP CONNECT proxies work consistently across runtimes:
export HTTP_PROXY="http://127.0.0.1:8080"
export HTTPS_PROXY="http://127.0.0.1:8080"
export http_proxy="http://127.0.0.1:8080"
export https_proxy="http://127.0.0.1:8080"Subprocess environment stripping
Subprocesses spawned by agents (git, gh, language servers) do not inherit shell session exports unless defined in ~/.zshrc or ~/.bashrc.
Diagnostic runbook: isolate and resolve the failure layer
Isolate whether drops stem from DNS, TLS handshakes, proxy configuration, NAT eviction, or IP reputation.
1. The curl timing probe
Measure latency and drop points against Anthropic's API:
curl -Iv -w "
--- Connection Breakdown ---\n\
DNS Lookup: %{time_namelookup}s\n\
TCP Connect: %{time_connect}s\n\
TLS Handshake: %{time_appconnect}s\n\
Pre-transfer: %{time_pretransfer}s\n\
Start Transfer: %{time_starttransfer}s\n\
Total Time: %{time_total}s\n\
HTTP Status: %{http_code}\n" \
https://api.anthropic.com/v1/messages- TCP Connect / TLS Handshake hangs (>5s): Middlebox filtering, packet loss, or high latency.
- HTTP Status 403: Egress IP blocked at Cloudflare edge due to ASN reputation.
- HTTP Status 400 or 401: Network path is healthy (Anthropic rejected the empty probe as expected).
2. Environment variable audit
Verify active proxy variables:
env | grep -iE 'proxy|anthropic|cursor|ssl|cert'Ensure HTTPS_PROXY points to an HTTP CONNECT proxy (http://127.0.0.1:8080), not raw SOCKS.
3. Claude Code diagnostic check
Run the CLI diagnostic suite:
claude doctorVerify whether reachability fails at transport or authentication.
4. IP reputation and ASN audit
Check exit node classification:
curl -s https://api.ipapi.is | jq '{ip, asn: .asn, asn_type: .company.type, is_vpn: .is_vpn, is_datacenter: .is_datacenter}'Verify your IP on scamalytics.com and iphey.com:
| Diagnostic Signal | Target Value | Problem Value |
|---|---|---|
ASN Type (company.type) | isp | hosting / datacenter |
| Is Datacenter / Is VPN | false | true |
| Scamalytics Fraud Score | 0–15 | 25+ (Immediate WAF flag at 45+) |
If company.type is hosting with elevated fraud scores, WAF blocks are expected.
5. Keepalive, DNS, and session recovery
- NAT Keepalive: Set
PersistentKeepalive = 25in WireGuard or proxy client configs to prevent state purging during tool runs. - DNS Isolation: Verify
api.anthropic.comresolves directly to Cloudflare Anycast edge IPs. - Stale State Recovery: If the CLI hangs after a drop, clear socket locks in
~/.claude/or restart Cursor's language server.
Route stability vs bandwidth: why coding agents break standard consumer VPNs
Consumer VPNs market raw throughput (10 Gbps for streaming). AI coding agents use under 50 KB/s, but require strict route stability and connection longevity:
- TCP keepalive consistency: Sockets need continuous
SO_KEEPALIVEprobes so firewalls do not drop idle connections during tool runs. - Deterministic routing: Consumer VPNs shift sockets across gateways to balance load. Mid-stream IP mutations trigger immediate Cloudflare session invalidation.
- Low packet jitter on TLS handshakes: Agent workflows run concurrent sub-requests. Packet loss during TLS negotiation causes cascading IDE timeouts.
A clean connection with ISP-grade routing and static session stickiness outperforms high-bandwidth datacenter proxies.
How to configure a stable setup with split tunneling
Routing all OS traffic through a VPN adds friction for localhost, Docker, and package managers. Use split tunneling to route AI endpoints through a clean path while leaving local development traffic on your default interface.
[Local Machine]
|
+---> Local Dev / Git / Docker -------> Default Direct Interface (Local ISP)
| (localhost, github.com, npm)
|
+---> AI Agent Endpoints -------------> Clean Network Path (Stable ISP ASN)
(api.anthropic.com, claude.ai,
api.cursor.sh, auth0.openai.com)Essential domain routing rules
Route traffic for these domains through your clean egress node:
# Anthropic & Claude Code
api.anthropic.com
claude.ai
# Cursor IDE
api.cursor.sh
# Authentication & edge infrastructure
auth0.openai.com
challenges.cloudflare.comMonitor outbound connections during active agent runs to capture release-specific telemetry and CDN subdomains.
Configuring explicit proxy endpoints for Claude Code
Export proxy variables before launching the CLI:
# In your ~/.zshrc or deployment script:
export HTTP_PROXY="http://127.0.0.1:8080"
export HTTPS_PROXY="http://127.0.0.1:8080"
export NO_PROXY="localhost,127.0.0.1,*.local"
# Launch Claude Code with clean inheritance
claudeA path built for AI engineering — stable routing, low occupancy, consistent egress — targets the shared-datacenter bad-neighbour problem at its root rather than working around it. dropweb is built for that case; before committing long agent runs to any provider, ours included, verify its egress classification with the ASN check above.
Related: Why standard VPNs get AI accounts flagged (The datacenter ASN problem) · Claude "Account disabled after automatic review" post-mortem · ChatGPT unusual activity and Auth0 403 blocks · The Cloudflare Turnstile verification loop.





