Troubleshooting
Proxy is unreachable
Section titled “Proxy is unreachable”Check the process and liveness route:
curl http://127.0.0.1:18765/healthzA healthy listener returns {"ok":true}. Confirm ANTHROPIC_BASE_URL uses the same address and port. claude-code-proxy serve --port 11435 and PORT=11435 change the listener port. --port wins for that command.
Setup page is locked or shows HTTP 401
Section titled “Setup page is locked or shows HTTP 401”Obtain a fresh private link from the same profile that serves the UI:
claude-code-proxy ui --print-url# For Docker with the default host port:docker compose exec proxy claude-code-proxy ui --print-url# For a published host port of 18766:docker compose exec proxy claude-code-proxy ui --print-url --url http://127.0.0.1:18766A native CLI with another CCP_CONFIG_DIR prints another profile’s key. Run the CLI inside the container for its profile. The inference placeholder ANTHROPIC_AUTH_TOKEN=unused does not unlock setup. The page removes the bootstrap fragment and retains its key for the tab session; reopening a bare /ui/ link in a new tab can require the private link again.
HTTP 403 indicates a rejected Host or origin. Open the UI on its loopback URL and keep the browser and management requests on the same origin. Publishing the container to a LAN address does not make the management UI a shared service.
Disconnect or sign in reports an active request
Section titled “Disconnect or sign in reports an active request”Setup returns HTTP 409 while the provider has active inference or token refresh work. A blocking refresh can continue after its caller disconnects, so wait for it to finish and retry. During a conflicting guided login, inference returns HTTP 503 with Retry-After: 2. Complete or cancel sign in in the provider dialog.
A failed or malformed login response preserves the previous working credential. Use the provider’s native auth command for detailed authorization diagnostics; avoid sharing raw tokens or private setup links.
Container starts, but Claude Code cannot connect
Section titled “Container starts, but Claude Code cannot connect”Inspect the published port and health:
docker compose psdocker compose logs --tail 100 proxyUse the host port, such as http://127.0.0.1:18766, in Claude Code’s ANTHROPIC_BASE_URL. The proxy still listens on 18765 inside the container. A source checkout’s private .env can change CCP_HOST_PORT; docker compose ps shows the active mapping. If you change ports, update the endpoint in Connection and session preferences and copy a fresh command.
An existing native proxy may already use port 18765. Follow Choose a host port to run both. If expected logins are missing after recreation, check the Compose project name and profile volume: a different project name selects a different volume. docker compose down --volumes removes the saved profile. See Docker setup and updates before removing volumes.
The UI retries status reads after a restart and clears its unavailable warning when the service returns. A profile with an unsupported schema is preserved and blocks setup until a compatible application or profile is restored.
Authentication error
Section titled “Authentication error”Check the provider selected by the model, then inspect its credential:
claude-code-proxy codex auth statusclaude-code-proxy kimi auth statusclaude-code-proxy grok auth statusclaude-code-proxy cursor auth statusUse that provider’s sign in dialog or login command when credentials are missing. An expired access token may refresh during verification; sign in again if refresh fails. Codex requires ChatGPT subscription auth, not an OpenAI API key. Each provider uses proxy-owned credentials.
OpenCode Go has no auth status command; save its API key in the setup UI or configure it through
CCP_OPENCODE_API_KEY, OPENCODE_API_KEY, or opencode.apiKey in
config.json.
Model returns HTTP 400
Section titled “Model returns HTTP 400”Run:
claude-code-proxy modelsclaude-code-proxy models --fullAn unknown local ID returns a catalog in the error. A known ID can still be rejected upstream when the account, subscription, or region lacks access. Cursor’s prefixed form, such as cursor:gpt-5.5, forces Cursor routing and avoids cross-provider collisions.
Cursor returns not_found after an upgrade
Section titled “Cursor returns not_found after an upgrade”A model can appear in claude-code-proxy models --full while an older proxy process still serves Claude Code. Installing a new executable does not replace a running process. The CLI catalog and the listener can therefore use different protocol implementations.
On macOS or Linux, identify the listener and its executable:
lsof -nP -iTCP:18765 -sTCP:LISTEN# Replace <pid> with the listener's PID from the preceding command.lsof -a -p <pid> -d txtcommand -v claude-code-proxyclaude-code-proxy --versionStop the old server in its terminal or through its service manager, then start the intended executable with serve. If several installations exist, use its absolute path. Restarting clears pending Cursor tool runs, so do this between requests. Retry a short prompt before resuming a longer conversation.
Copy the exact model selection from the current account catalog and quote shell assignments containing brackets, for example ANTHROPIC_MODEL='cursor:gemini-4-argon[reasoning_effort=high]'. A catalog entry establishes discovery; a successful inference request establishes that the running server and account can use it. If the current server still returns not_found, inspect the selected provider and model in its diagnostics before changing aliases or credentials.
Background requests fail
Section titled “Background requests fail”Set ANTHROPIC_DEFAULT_HAIKU_MODEL to a concrete routable ID. Claude Code sends title and small background tasks through that model independently of the main model.
A tool runs twice
Section titled “A tool runs twice”Set CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK=1 for Claude Code. Retrying a partially completed stream as non-streaming can duplicate tool calls.
Session reaches context limits
Section titled “Session reaches context limits”[1m] changes Claude Code’s local compaction threshold and does not enlarge upstream context. Use a safe CLAUDE_CODE_AUTO_COMPACT_WINDOW, remove [1m], or compact earlier. For ChatGPT GPT-5.6 subscription models, 272000 is the documented setup value.
Codex WebSocket fails
Section titled “Codex WebSocket fails”For a non-TUN local HTTP proxy, set both destination-scheme variables before starting the proxy:
| Variable | Value |
|---|---|
HTTP_PROXY |
http://127.0.0.1:7890 |
HTTPS_PROXY |
http://127.0.0.1:7890 |
Set them through the operating system, service manager, or shell, then start claude-code-proxy serve in the same environment.
The default wss://chatgpt.com connection uses HTTPS_PROXY; a working proxy should show CONNECT chatgpt.com:443. The http:// value is normal: it describes how to reach the proxy, while HTTPS_PROXY describes which destinations use it. Restart claude-code-proxy after changing these variables because the client and pooled WebSocket route are created at startup.
Check NO_PROXY when the proxy sees no request. Proxy connection, authentication, or CONNECT failure is returned as an error and never retried directly. Environment variables are supported; OS proxy settings and PAC/WPAD discovery are not automatic.
Use HTTP SSE to isolate transport behavior:
CCP_CODEX_TRANSPORT=http claude-code-proxy serveauto falls back only when WebSocket setup fails before sending the request. It does not replay an in-flight request.
Cursor models are missing or rejected
Section titled “Cursor models are missing or rejected”Check the proxy-owned login and refresh the account catalog:
claude-code-proxy cursor auth statusclaude-code-proxy models --fullThe native provider does not load a Cursor Agent JavaScript bundle.
CCP_CURSOR_AGENT_BUNDLE is a legacy setting with no effect. If authentication
has expired, run claude-code-proxy cursor auth login again. An installed
cursor-agent supplies the client version when available; use
CCP_CURSOR_CLIENT_VERSION only for a controlled compatibility check.
Account and administrator policies can still block a listed model. Inspect the upstream error in the monitor or structured log. See Cursor Agent for discovery, parameter selections, and account boundaries.
Rate limited
Section titled “Rate limited”Upstream limits are shared with other clients on the same account. Codex limit responses and Kimi HTTP 429 responses surface as HTTP 429 with retry-after. Wait for the indicated interval or reduce concurrent traffic.
Find the complete error
Section titled “Find the complete error”The monitor shows request detail. proxy.log contains structured JSONL events, and errors/ stores complete redacted failed-response payloads. A request_failed event includes the error file path.
For a source checkout, run the isolated helper:
./scripts/debug-proxyIt prints a random local URL, a sourceable client.env, and artifact paths. Keep the terminal open, reproduce once, then press Ctrl-C. Captures contain sensitive prompt and tool content.
Focused traffic capture
Section titled “Focused traffic capture”CCP_LOG_VERBOSE=1 \CCP_TRAFFIC_LOG=1 \ claude-code-proxy serve --no-monitorTraffic capture writes the inbound request, translated upstream request, upstream headers and events, and downstream events in emission order. Known credentials are redacted, but prompts and tool content are preserved. Disable capture and delete artifacts after diagnosis.