Skip to content

MCP OAuth: shared brokered token state goes stale across devices; surfaces as -32603 Internal error on every tool call instead of a re-auth prompt #35344

Description

@agcty

Summary

We operate a remote MCP server (streamable HTTP) with an OAuth 2.1 issuer (rotating refresh tokens, S256 PKCE, RFC 8414/8707/9728, CIMD client support). On 2026-07-25, Codex CLI failed every tool call against this server on two devices simultaneously with:

tool call error: tool call failed for `codex_apps/<server>.<tool>`
Caused by:
    Mcp error: -32603: Internal error

— including zero-argument tools (whoami). codex mcp login <server> on the affected device resolved it.

We investigated from the server side before finding the client-side cause, and are reporting because the server-side evidence shows two distinct issues that user-side reports probably can't demonstrate.

Server-side evidence

Failure window ≈ 11:00–11:50 UTC, 2026-07-25.

  1. The failing requests never left the client. Worker request logs (100% sampling) show zero requests from the openai-mcp/1.0.0 (ChatGPT) user agent to the MCP endpoint during the window. Before and after it, requests from that UA return 200. No 401/403 was issued to any OpenAI-related UA at any point; no token-endpoint failures either.
  2. The refresh chain kept rotating successfully during the outage. The account's grant shows successful refresh rotations at 10:05:52Z and 11:01:37Z — from OpenAI backend user agents (python-httpx/0.28.1, Python/3.12 aiohttp/3.13.5) — while both devices were failing.
  3. All surfaces share one brokered token chain. The grant's refresh-token lineage is a single, perfectly linear rotation chain (25 rotations over 8 days, one root, no forks) covering two Codex CLI devices and the ChatGPT connector. The client_id is the CIMD document https://chatgpt.com/oauth/2Dpr-r7e86Dn/client.json, and only backend UAs ever hit /oauth/token — so token state appears to be held and refreshed server-side by OpenAI, shared across the user's devices.
  4. codex mcp login did not re-authorize. The recovery at 11:52:45Z created no new authorization (no consent, no new chain root); it continued the existing chain as an ordinary refresh rotation.

The two issues

1. Shared token state goes stale and does not self-recover. With one rotating refresh chain shared across all of a user's devices/surfaces, some holder's view of the current token went stale (the chain had moved on at 10:05Z/11:01Z) and stayed broken until a manual codex mcp login — which itself just performed a refresh, i.e. the credential was recoverable all along. Whatever holds the brokered state could presumably re-fetch/retry instead of entering a terminal state. Note that OAuth 2.1 §4.3.1 reuse detection makes this failure mode sharp for servers to tolerate: a holder more than one rotation behind that does present its stale token would trip theft detection and revoke the credential family, so client-side serialization of refreshes on a shared chain matters. Possibly related: #26586.

2. The failure surfaces as -32603: Internal error instead of an auth error. Every tool call fails with a generic JSON-RPC internal error, indistinguishable from a server-side fault — the message even says the tool call failed, though no request was ever dispatched. An OAuth refresh failure should surface as an authentication problem (re-auth prompt, as on initial 401), not as an internal error. This rendering cost us a full server-side investigation (logs, token-table forensics) to rule out our own infrastructure before concluding the requests never arrived.

Environment

  • codex-cli 0.144.0, macOS (both devices)
  • Server: streamable HTTP MCP, stateless POST transport; OAuth 2.1 issuer with rotating refresh tokens (~1h access / ~30d refresh TTL), single-step rotation grace

Happy to provide redacted log excerpts or timestamps in more detail.

Metadata

Metadata

Assignees

No one assigned

    Labels

    CLIIssues related to the Codex CLIauthIssues related to authentication and accountsbugSomething isn't workingmcpIssues related to the use of model context protocol (MCP) serverstool-callsIssues related to tool calling

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions