WebSocket handshake to wss://api.openai.com/v1/responses fails with 401 Missing bearer when signed in via ChatGPT OAuth (v0.153.4)
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
Summary
With ChatGPT OAuth sign-in, Codex CLI 0.153.4 attempts a WebSocket connection to wss://api.openai.com/v1/responses that fails with:
401 Unauthorized: Missing bearer or basic authentication in header
The client retries 5 times, falls back to HTTP, then attempts a token refresh that also fails, which logs the user out. Codex becomes unusable with ChatGPT sign-in.
Environment
- codex-cli 0.153.4 (Windows x64)
- Auth mode: ChatGPT OAuth (
codex login) - Network: behind a proxy; HTTP requests to
chatgpt.comandauth.openai.comsucceed
Steps to reproduce
codex loginwith a ChatGPT accountcodex exec "hello"
Observed logs
ERROR codex_api::endpoint::responses_websocket: failed to connect to websocket: HTTP error: 401 Unauthorized, url: wss://api.openai.com/v1/responses
WARN codex_core::session_startup_prewarm: startup websocket prewarm setup failed: unexpected status 401 Unauthorized: Missing bearer or basic authentication in header, url: wss://api.openai.com/v1/responses
WARN codex_core::responses_retry: stream disconnected - retrying sampling request (1/5 in 214ms)... sampling_error=unexpected status 401 Unauthorized: Missing bearer or basic authentication in header, url: wss://api.openai.com/v1/responses
... (retries 2..5 with the same 401) ...
WARN codex_core::client: falling back to HTTP
ERROR codex_login::auth::manager: Failed to refresh token: 401 Unauthorized: {"code":"token_expired"}
ERROR: Your access token could not be refreshed. Please log out and sign in again.
Expected
Either the WebSocket handshake should include the same Authorization header that the HTTP path uses, or the WebSocket attempt should be skipped entirely when the auth mode is ChatGPT OAuth.
Evidence that the same token works over HTTP
Using the identical access token from the same auth.json:
GET https://chatgpt.com/backend-api/codex/models?client_version=0.153.4
Authorization: Bearer <access_token>
ChatGPT-Account-ID: <account_id>
=> HTTP 200 with the full model list
So the token itself is valid and accepted; only the WebSocket handshake fails to attach authentication.
Impact
- Codex cannot be used at all with ChatGPT sign-in: the failed WebSocket causes a retry loop, then a token refresh, which fails and logs the user out.
auth.jsoncontains a validaccess_token(JWTexp~10 days in the future), so the failure is unrelated to token expiry on the HTTP path.
Attempted workarounds (none work on 0.153.4)
config.toml:
[experimental]
responses_websockets = false
config.toml:
[features]
responses_websockets = false
responses_websockets_v2 = false
- Inserting
responses_websockets = 0into~/.codex/sqlite/codex-dev.db, tablelocal_app_server_feature_enablement.
All three configurations still result in the WebSocket connection attempt, so there is currently no way to disable WebSocket transport.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with codex_api::endpoint::responses_websocket and compare its handshake setup with the authenticated HTTP path. Trace the interaction with codex_core::session_startup_prewarm, codex_core::responses_retry, and codex_login::auth::manager using the reproduction steps. Done means ChatGPT OAuth requests either authenticate over WebSocket or skip that transport without retrying into logout.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api, authentication, cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100