Skip to content

MCP OAuth: Codex does not re-register (DCR) on invalid_client / expired refresh token — requires manual re-auth #29630

Open

Description

@julianduque

Summary

When an MCP server's refresh token is rotated or expired, Codex logs Token refresh not possible, re-authorization required and stops. It does not discard the dead client_id and POST to the advertised registration_endpoint to re-register, as OAuth 2.1 / the MCP Dynamic Client Registration (DCR) spec expect. Users must manually log out and re-add the server to recover.

Evidence

From ~/.codex/logs_2.sqlite (target rmcp::transport::auth):

Access token expired or nearly expired, refreshing. remaining_secs=0
refresh token present, attempting refresh
Token refresh not possible, re-authorization required.
  error=OAuth token refresh failed: Server returned error response: invalid_grant: refresh token ...

After this point there is no subsequent /register call — the flow just halts. Over the lifetime of this install: 0 events handling invalid_client, only 3 /register events total.

Tested against a spec-compliant FastMCP OAuthProxy server that, for an unknown/stale client_id, returns:

  • POST /token → 401 {"error":"invalid_client"}
  • GET/POST /authorize → 400 {"error":"invalid_request","error_description":"Client ID '...' is not registered with this server. MCP clients should automatically re-register by sending a POST request to the registration_endpoint and retry authorization...","registration_endpoint":"https://.../register"}

The server explicitly advertises the registration_endpoint and instructs the client to re-register. Codex ignores it.

Environment: Codex CLI 0.142.0 (macOS, compiled Rust binary). MCP OAuth credentials stored in macOS Keychain under service Codex MCP Credentials.

Impact

Any MCP server that rotates refresh tokens or restarts (losing server-side token state) logs every user out until they manually re-authenticate. codex mcp logout is an unreliable workaround — it is per-server/per-URL-hash scoped and has known cleanup gaps (#25002, #28201).

Expected behavior

On invalid_client (or an unrecoverable refresh failure), Codex should automatically discard the stored client_id + tokens, re-run dynamic client registration against the server's advertised registration_endpoint, and retry authorization — per the MCP authorization spec — rather than stopping and requiring manual intervention.

Activity

  1. added
    bugSomething isn't working
    CLIIssues related to the Codex CLI
    mcpIssues related to the use of model context protocol (MCP) servers
    authIssues related to authentication and accounts
    on Jun 23, 2026
  2. github-actions commented on Jun 23, 2026

    @github-actions
    Contributor

    Potential duplicates detected. Please review them and close your issue if it is a duplicate.

    Powered by Codex Action

  3. julianduque commented on Jun 23, 2026

    @julianduque
    Author

    Adding full environment details:

    macOS 26.5 (build 25F71)
    Codex CLI 0.142.0 (codex-cli 0.142.0, installed via Volta / npm @openai/codex)
    Codex Desktop 26.616.71553 (build 4265)

    Both the CLI and the Desktop app exhibit the behavior — they share ~/.codex, and MCP OAuth credentials are stored in the macOS Keychain under service Codex MCP Credentials.

  4. awhitford commented on Sep 7, 2026

    @awhitford

    Cross-link for triage: this is a mechanism-specific member of the same cluster as #39054 (CLI/app-server) and #38198 (Desktop surface) — all three are "Codex halts on a failed refresh and never recovers / never surfaces re-auth." This issue adds the specific, stronger fix: on invalid_client (dead client_id), discard it and re-POST to the advertised registration_endpoint per the MCP DCR spec, which would auto-recover with zero manual steps rather than just surfacing an Authenticate button.

    Separate from the #14144 / #32590 cluster (re-login succeeds but the running session keeps stale creds until restart).

  5. grtninja commented on Sep 29, 2026

    @grtninja

    Adding a data point from the third-party side, in case something changed server-side.

    A third-party OAuth client (OpenClaw's "Sign in with ChatGPT" beta flow) is getting invalid_client at the consent step — auth.openai.com/sign-in-with-chatgpt/consent renders "This app is unavailable. Contact the app owner" before any user authentication occurs (observed 2026-09-29, request_id 3eod09c0-890b-428a-9301-a780cd03e9ea).

    Update: a direct OpenAI login from the same machine/browser succeeded minutes later (OpenAI's own "new sign-in" notification, 9:47 AM EDT). Account and credentials are fine — the failure is isolated to the beta consent page's client registration. That rules out the account side entirely; it's the client registration or the consent-page validation around it.

    The client's own registration is the prime suspect (tracked at openclaw/openclaw#161216), but flagging here because if auth-server validation tightened recently, other third-party clients may hit the same wall. Happy to provide more detail if it's useful for triage.

    — Muse for @grtninja

  6. grtninja commented on Sep 29, 2026

    @grtninja

    One more note from the reporter: he's out of Codex usage quota, so he can't drive further repro or debugging from his side. The evidence above (both error codes, request IDs, and the firsthand full-ceremony bounce) is everything he can provide — he'd appreciate a maintainer picking up the client-identification step from here.

    — Muse for @grtninja

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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) servers

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions