[BUG] VS Code integrated terminal: every request fails with 503 'pre-upstream queue is saturated'; native Terminal.app works (macOS)

Status Fixed / completed
Reported on v2.1.193
Maintainer reply None cached
Activity 5 comments · opened Jun 26, 2026 · closed Jun 29, 2026

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?

Running claude from the VS Code integrated terminal hangs ~15s on every request and then fails with a 503 service_unavailable ("pre-upstream queue is saturated"), retrying up to 11 times and never returning. Running the exact same binary from the native macOS Terminal.app returns a response in ~2–3 seconds, every time, with no retries.

The behavior is consistent, not intermittent: VS Code fails on every attempt, native succeeds on every attempt, including when run within the same time window.

Critically, debug logs show the request that gets sent is identical in both environments (source=sdk, same entrypoint, same model, same auth), and curl to the same endpoint succeeds instantly from both terminals. So this is neither a network issue nor a request-content difference — something about how the VS Code-spawned process establishes the API connection causes it to consistently land on a failing/saturated path.

What Should Happen?

claude -p "hi" from the VS Code integrated terminal should return a response in ~2–3s, the same as from native Terminal.app.

Error Messages/Logs

The outbound request is the same kind in both terminals; only the outcome differs.

**Native (`claude -p "hi"`, succeeds):**

[API REQUEST] /v1/messages x-client-request-id=dbce45c4-... source=sdk
... cc_entrypoint=sdk-cli; cch=00000;
Stream started - received first chunk
[API:timing] first byte after 2311ms


**VS Code (`claude -p "hi"`, fails):**

[API REQUEST] /v1/messages source=sdk
... cc_entrypoint=sdk-cli;
API error (attempt 1/11): 503 {"type":"error","error":{"type":"service_unavailable","message":"Anthropic pre-upstream queue is saturated. Please retry shortly."}}
API error (attempt 2/11): 503 ... (same)
... continues retrying ...


Same `source=sdk`, same `cc_entrypoint=sdk-cli`, same model, same OAuth auth. Native streams a first byte in 2.3s; VS Code waits ~15s per attempt and gets a 503 each time.

Steps to Reproduce

  1. On macOS, open VS Code with the Claude Code extension installed/active.
  2. Open the integrated terminal and run claude -p "hi".
  • Observed: hangs ~15s, then API error (attempt 1/11): 503 service_unavailable, retries repeatedly, never returns.
  1. Open native Terminal.app, cd to the same project, run claude -p "hi".
  • Observed: returns a response in ~2–3s, no retries.

Note: the request that leaves the process is identical in both terminals (source=sdk, cc_entrypoint=sdk-cli, same model, same OAuth auth), and curl to the same endpoint succeeds instantly from both — so it is not network or request content.

Claude Model

Other

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.193 (cc_version=2.1.193.45e)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

VS Code integrated terminal

Additional Information

Environment

  • Install method: npm-global, under nvm node v24.4.1 (/Users/<user>/.nvm/versions/node/v24.4.1/lib/node_modules/@anthropic-ai/claude-code)
  • Editor: VS Code 1.126.0
  • Plan / auth: Claude Max, OAuth (no API key; has Authorization header: false, OAuth token check passes)
  • Model: claude-haiku-4-5-20251001
  • Shells tested: native Terminal.app (zsh login shell) and VS Code integrated terminal (zsh)

Additional evidence

Network path is identical and healthy in BOTH terminals

Direct curl to the failing endpoint, run in each terminal:

time curl -sS -o /dev/null -w "%{http_code} %{time_total}s\n" \
  -X POST https://api.anthropic.com/v1/messages \
  -H "content-type: application/json" -d '{}'
  • Native: 401 0.228615s
  • VS Code: 401 0.504596s

Both reach /v1/messages instantly (401 expected with empty/unauthed body). Rules out network, proxy, DNS, TLS/cert as the cause.

No proxy / Node TLS env differences

env | grep -i proxy returns nothing in both terminals. NODE_EXTRA_CA_CERTS, NODE_OPTIONS, NODE_TLS_REJECT_UNAUTHORIZED are all empty in both. (The mTLS: Creating HTTPS agent with custom certificates debug line appears in all runs including native — it is internal Claude Code behavior, not user cert config.)

Removing VS Code IDE integration does NOT fix it

  • env -u CLAUDE_CODE_SSE_PORT claude -p "hi" → still hangs.
  • env -u CLAUDE_CODE_SSE_PORT TERM_PROGRAM=xterm-256color claude -p "hi" → still hangs, with no IDE detection at all in the log (no ide MCP server, no SSE connection, no IDE lock-file logic) and still 503-loops.

Other things tested and ruled out

  • MCP fully disabled — claude --strict-mcp-config --mcp-config '{"mcpServers":{}}' in the VS Code terminal. Still 503s. Rules out any MCP server (including the ide and claude-in-chrome servers).
  • IDE lock files cleared — deleted ~/.claude/ide/*.lock (and the whole ~/.claude/ide/ directory), fully quit and reopened VS Code so a fresh lock/port is written. No change. Rules out the stale-lock-file mechanism described in #67897 / #42141.
  • CLAUDE_CODE_SSE_PORT unset — still hangs.
  • Plugins — failure occurs regardless; reduced to 3 plugins (context7, playwright, typescript-lsp) with no effect.

So the failure is not the IDE/SSE channel, not stale IDE lock files, not MCP, and not plugins.

Analysis / where it points

With network proven healthy in both terminals (curl) and the outbound request proven identical (debug logs), the difference cannot be in what is sent. It must be in how the VS Code-spawned Node process establishes/handles the HTTPS connection to the API — e.g. connection routing, socket/agent reuse, or runtime/networking inherited from the VS Code parent process — causing it to consistently hit a saturated server frontend while the native-shell process does not.

The 503 body (pre-upstream queue is saturated) is a server-side capacity signal, but the consistent per-terminal split (native always succeeds, VS Code always 503s) suggests it is not purely random load.

Workaround

Run Claude Code from native Terminal.app (works 100% of the time). VS Code can stay open as the editor alongside it. This loses the in-editor integration (diff tabs, IDE file context) but is fully functional.

What would help confirm

A same-second side-by-side capture (native + VS Code firing simultaneously) to definitively separate "server timing/load" from "VS Code-spawned process routes differently." The VS Code side hangs, so a strictly simultaneous capture was not possible.

Related issues

  • #25253 — VSCode Plugin hangs after first request, terminal works fine (closest match)
  • #41031 — Claude Code freezes in VS Code, only native Mac Terminal works (macOS)
  • #30417 — VS Code extension hangs indefinitely, CLI works at all times (macOS)
  • #67897, #42141 — stale CLAUDE_CODE_SSE_PORT hangs (ruled out here)

View original on GitHub ↗

5 Comments

yurukusa · 3 months ago

Nice isolation work — you've already ruled out the two usual culprits (request content and raw network), since the debug request is byte-identical and curl succeeds from both terminals. That leaves exactly one variable: the environment the process inherits from its parent. VS Code's integrated terminal injects a different env than Terminal.app, and 503 "pre-upstream queue is saturated" is a server-side gateway/queue response — so something the VS Code-spawned process carries is routing its connection onto a throttled/saturated upstream path, even though the request body is the same. Because curl works from the same VS Code terminal but the CLI doesn't, the difference is almost certainly in the transport layer (proxy / TLS / HTTP version / connection reuse), which Node's HTTP client (undici) and curl handle with different env semantics — not in anything you typed.

Fastest way to pin it down:

1. Diff the two environments. From the VS Code integrated terminal:

env | sort > /tmp/vscode-env.txt

From Terminal.app:

env | sort > /tmp/native-env.txt

then

diff /tmp/native-env.txt /tmp/vscode-env.txt

The lines that only exist on the VS Code side are your suspect list.

2. Re-run with the likely suspects stripped. In the VS Code terminal:

env -u HTTPS_PROXY -u HTTP_PROXY -u ALL_PROXY -u NO_PROXY \
    -u NODE_OPTIONS -u NODE_EXTRA_CA_CERTS \
    claude -p "hi"

If that returns in ~2–3s, the cause is one of those injected vars (unset them one at a time to find which).

3. If it persists, try a near-clean env (keep just what auth/PATH need):

env -i HOME="$HOME" PATH="$PATH" TERM="$TERM" claude -p "hi"

A clean-env success confirms it's an inherited variable, not the binary or VS Code's PTY itself.

My leading guess is a proxy variable: VS Code (and some extensions/corporate setups) export HTTP(S)_PROXY into the integrated terminal pointing at a loopback or gateway proxy. Node/undici will route through it and can coalesce many short requests onto one upstream connection — which is exactly what produces "pre-upstream queue is saturated" under retry — while curl's proxy/keep-alive handling differs enough to dodge it. The env diff in step 1 will confirm or kill that quickly. (I'm reasoning from the transport behavior here, not asserting it's definitely proxy — the diff is what makes it certain.)

---

For the maintainers: this is a good repro that the failing path is environment-inherited transport behavior, not request content — identical source=sdk request, identical endpoint, curl fine from both terminals, only the VS Code-spawned process consistently lands on the saturated upstream and burns all 11 retries. Worth checking whether the CLI's HTTP client is honoring an inherited proxy / connection-pooling setting that VS Code injects and Terminal.app doesn't, and whether a 503 pre-upstream queue is saturated should even be retried 11× (it reads like client-side connection coalescing being mistaken for a server rate signal).

techsin · 3 months ago

Ran the env diff (thanks @yurukusa). Sanitized env | sort from both terminals, then diffed. Headline: the transport vars the theory points at aren't present on either side — no HTTP_PROXY / HTTPS_PROXY / ALL_PROXY / NO_PROXY, and no NODE_OPTIONS / NODE_EXTRA_CA_CERTS in the VS Code env or the native one. So an inherited proxy/TLS variable doesn't look like the cause.

Everything the VS Code integrated terminal injects that Terminal.app doesn't is shell-integration / editor scaffolding, not networking (sanitized; values redacted where sensitive):

CLAUDE_CODE_SSE_PORT=21775
COPILOT_DEBUG_NONCE=<redacted>
GIT_ASKPASS=<redacted>
MallocNanoZone=0
USER_ZDOTDIR=/Users/<user>   ZDOTDIR=/Users/<user>
VSCODE_GIT_ASKPASS_EXTRA_ARGS / _MAIN / _NODE=<redacted>
VSCODE_GIT_IPC_HANDLE=…/T/vscode-git-…sock
VSCODE_INJECTION=1   VSCODE_PROFILE_INITIALIZED=1   VSCODE_PYTHON_AUTOACTIVATE_GUARD=1
__CFBundleIdentifier=com.microsoft.VSCode   __CF_USER_TEXT_ENCODING=0x1F5:0x0:0x0

LANG: en_US.UTF-8 (native) → C.UTF-8 (VS Code)
PATH: VS Code prepends the GitHub Copilot extension's copilotCli/debugCommand dirs + the VS Code app bin

CLAUDE_CODE_SSE_PORT is the only network-ish entry and it's already ruled out (unsetting it / suppressing IDE detection doesn't help). Nothing here is a proxy, a Node HTTP/TLS setting, or anything that should change which upstream the request lands on. (Ignore PWD/OLDPWD differing — I just ran the two captures from different directories.)

Net: this argues against an inherited-env explanation and back toward how the VS Code-spawned process is created, not what it inherits or sends. Decisive next test on my side is the clean-env run — env -i HOME="$HOME" PATH="$PATH" TERM="$TERM" claude -p "hi"; if it still 503-loops with a near-empty environment, env is fully excluded. Will follow up with that.

techsin · 3 months ago

Clean-env test: still fails. Ran the near-empty environment in the VS Code integrated terminal:

env -i HOME="$HOME" PATH="$PATH" TERM="$TERM" claude -p "hi"

Still hangs and 503-loops (pre-upstream queue is saturated). From Terminal.app it returns in ~2–3s, as always.

So environment variables are fully excluded. With only HOME/PATH/TERM set — no VSCODE_*, no shell-integration vars, no CLAUDE_CODE_SSE_PORT, nothing — the VS Code-spawned process still lands on the saturated path while a native login shell doesn't. Combined with the earlier evidence (identical source=sdk request, curl fine from both terminals, no proxy/NODE_* vars in either env), nothing inherited as an environment variable explains it.

That leaves the process/launch context itself: how the CLI is spawned and parented under VS Code (PTY, parent process tree, inherited fds/sockets) versus a login shell — not its environment and not its request. Worth a maintainer looking at whether the HTTP client's connection behavior depends on that launch context, and (echoing @yurukusa) whether a 503 pre-upstream queue is saturated should be retried 11× at all rather than surfaced.

techsin · 3 months ago

Resolved — this was my own config, not a Claude Code bug. Closing.

Root cause was a project-local override in this folder's .claude/settings.local.json:

"env": { "ANTHROPIC_BASE_URL": "http://127.0.0.1:8787" }

That routed every request through a local gateway (a queue manager I run on :8787) instead of api.anthropic.com. Its queue was saturated, which is where the pre-upstream queue is saturated 503 and the hang/retries came from — and it only reproduced inside this folder, because that's where the project settings load.

This also unwinds the "VS Code vs Terminal.app" framing in the comments above: that was a directory confound — I ran the native capture from ~ and the VS Code one from the project dir. Terminal.app inside the folder fails identically, and the extension hangs because it operates on the same workspace. curl and the env diff looked clean because the override isn't a shell env var (Claude injects it from the settings file) and curl hit api.anthropic.com directly.

Fix: removed the ANTHROPIC_BASE_URL override; Claude goes direct again and returns in ~2–3s inside the folder. If anything's actionable on the Claude Code side, it'd only be surfacing a gateway 503 sooner instead of an 11× hang — minor. Thanks @yurukusa for the steer. Closing as resolved — not a Claude Code issue.

github-actions[bot] · 1 month ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.