codex mcp-server: transient "Auth(AuthorizationRequired)" when spawning multiple concurrent stdio server instances

Open 💬 2 comments Opened Jul 5, 2026 by ryangu00

Summary

Running codex mcp-server (ChatGPT-subscription login, no API key) as a stdio MCP server, spawned as independent child processes (each invocation does spawn("codex", ["mcp-server"]), fresh process per task, no shared state between them), I observe intermittent transport failures:

ERROR rmcp::transport::worker: worker quit with fatal: Transport channel closed, when Auth(AuthorizationRequired)

Observed evidence (from real logs tonight, timestamps included)

Two codex mcp-server processes were spawned within the same second, dispatched from two separate tools/call requests issued almost simultaneously:

  • Process A: failed at 2026-07-05T21:06:33.754284Z with the error above
  • Process B: succeeded, dispatched at essentially the same wall-clock moment

Across one evening of usage I logged 4 failures out of 23 total codex mcp-server invocations (17.4%), so this is not a rare one-off.

What I've ruled out

  • Not a bug in my client: my stdio client is a minimal NDJSON wrapper (initializenotifications/initializedtools/call), it does not touch auth at all.
  • Not a permanently-expired session: codex login status and codex doctor both show a healthy, currently-valid ChatGPT auth (stored ChatGPT tokens: true) immediately after the failures.
  • codex doctor shows the ChatGPT backend auth path is a WebSocket connection (wss://chatgpt.com/backend-api/..., handshake HTTP 101 Switching Protocols) — this may be relevant to why concurrent process spawns racing for auth could produce a transient channel-closed error.

Environment

  • codex-cli 0.142.5 (installed via brew)
  • macOS 26.5.1 (Apple Silicon)
  • Auth mode: ChatGPT subscription (not API key)

Question for maintainers

Is there a known race condition when multiple codex mcp-server processes are spawned concurrently and each performs its own auth handshake against the shared ChatGPT session/token store? Is there a recommended way to avoid this (e.g., serializing server startup, a shared auth-refresh lock, or a codex config flag to increase auth-handshake retry tolerance) rather than the caller having to retry externally?

I don't have a minimal concurrent-only repro isolated from my larger workflow yet — happy to try to produce one if useful. Filing this now with the real evidence I have, since the failure mode is disruptive enough (17% of invocations) that it seemed worth reporting even without a fully isolated repro.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗