Skip to content

codex mcp login fails with "No authorization support detected" on macOS against a spec-compliant OAuth server (same version works on Linux) #34684

Description

@mike-phys08

Summary

codex mcp login <server> fails instantly with Error: No authorization support detected
on macOS (arm64) against a fully spec-compliant OAuth 2.0 authorization server.
The same codex version completes the entire flow on Linux against the same server
(discovery → dynamic client registration → browser → token). Other MCP clients
(Claude Code, mcp-remote) complete OAuth against this server without issues —
including mcp-remote running on the same Mac, which rules out the machine's
network/TLS stack and the server itself.

A second, independent defect (RFC 9207 iss dropped when relaying the OAuth callback)
was found while debugging; see the last section. Happy to split it into its own issue.

Environment

  • codex-cli 0.144.6 (pins rmcp 1.8.0 per codex-rs/Cargo.lock of tag rust-v0.144.6)
  • macOS: 26.5.2, BuildVersion 25F84; uname -m = arm64 (Mac mini)
  • Install: official binary at ~/.local/bin/codex; also reproduced with the pristine
    release tarball
    codex-aarch64-apple-darwin.tar.gz from the rust-v0.144.6 GitHub
    release, executed directly
  • No proxies: env | grep -i proxy is empty; scutil --proxy shows only the default
    ExceptionsList (*.local, 169.254/16), no HTTP/HTTPS/SOCKS/PAC
  • Reproduced with a fresh CODEX_HOME (empty directory), so user config is not involved
  • RUST_LOG=debug codex mcp login <server> prints nothing beyond the error itself

Repro steps (macOS)

mkdir -p ~/codex-test && cd ~/codex-test
curl -LO https://github.com/openai/codex/releases/download/rust-v0.144.6/codex-aarch64-apple-darwin.tar.gz
tar xzf codex-aarch64-apple-darwin.tar.gz
mkdir home && export CODEX_HOME=~/codex-test/home
./codex-aarch64-apple-darwin mcp add sparrow --url https://mcp.example.com/mcp
# → Added global MCP server 'sparrow'.
# → Detected OAuth support. Starting OAuth flow…
# → Error: No authorization support detected
./codex-aarch64-apple-darwin mcp login sparrow
# → Error: No authorization support detected

(Hostname sanitized throughout: mcp.example.com = a self-hosted MCP server behind
nginx with a valid Let's Encrypt certificate, reachable over the public internet.)

Server capabilities

Self-hosted MCP server (Streamable HTTP) whose app is its own OAuth 2.0 authorization
server (OpenIddict 7.5):

  • 401 on /mcp with
    WWW-Authenticate: Bearer resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource"
  • RFC 9728 protected resource metadata at the root path and the path-suffixed variant
    (/.well-known/oauth-protected-resource/mcp)
  • RFC 8414 AS metadata at /.well-known/oauth-authorization-server (root and
    path-suffixed), plus /.well-known/openid-configuration
  • RFC 7591 dynamic client registration (registration_endpoint advertised; returns 201
    with a public PKCE client, token_endpoint_auth_method=none)
  • token_endpoint_auth_methods_supported includes "none"
  • authorization_servers[0] matches the AS issuer byte-for-byte (trailing slash included)
  • Authorization Code + PKCE (S256); response_types_supported: ["code"]

What the server sees during a failing macOS codex mcp login (nginx access log)

CLIENT_IP - - [20/Jul/2026:18:30:56 +0000] "GET /mcp HTTP/1.1" 401 0 "-" "-"
CLIENT_IP - - [20/Jul/2026:18:30:56 +0000] "GET /.well-known/oauth-protected-resource HTTP/1.1" 200 218 "-" "-"
CLIENT_IP - - [20/Jul/2026:18:30:56 +0000] "GET /.well-known/oauth-authorization-server HTTP/1.1" 200 1653 "-" "-"

All three requests succeed — then nothing. No fallback attempt to
/.well-known/openid-configuration, no POST to the registration endpoint. The CLI
prints Error: No authorization support detected immediately.

This should be impossible if the 200 AS-metadata response was actually processed:
rmcp 1.8.0's discover_metadata() returns NoAuthorizationSupport only after all
discovery candidates fail, and a successful parse of that document would have continued
to DCR (as it does on Linux, below). This suggests the login path's HTTP client fails
client-side on macOS, separately from the requests above.

Same binary version on Linux (x86_64) — full success

CLIENT_IP - - [20/Jul/2026:18:02:01 +0000] "POST /oauth/register HTTP/1.1" 201 261 "-" "-"
CLIENT_IP - - [20/Jul/2026:18:02:01 +0000] "GET /oauth/authorize?response_type=code&client_id=…&code_challenge=…&code_challenge_method=S256&redirect_uri=http%3A%2F%2F127.0.0.1%3A33721%2Fcallback%2F…&scope=openid+offline_access+mcp&resource=https%3A%2F%2Fmcp.example.com%2Fmcp HTTP/2.0" 302 0

codex mcp login output on Linux (after the RFC 9207 server-side workaround described
below): Successfully logged in to MCP server 'sparrow'. — codex mcp list shows
Status enabled / Auth OAuth.

mcp-remote from the SAME Mac — full success

CLIENT_IP - - [20/Jul/2026:18:58:26 +0000] "GET /oauth/authorize?…" 302 … "node"
CLIENT_IP - - [20/Jul/2026:18:58:26 +0000] "GET /.well-known/oauth-protected-resource/mcp HTTP/1.1" 200 218 "-" "node"
CLIENT_IP - - [20/Jul/2026:18:58:26 +0000] "POST /oauth/token HTTP/1.1" 200 4575 "-" "node"
CLIENT_IP - - [20/Jul/2026:18:58:26 +0000] "POST /mcp HTTP/1.1" 200 77092 "-" "node"   ← tools/list

Same machine, same network, same server: the stdio bridge (codex mcp add sparrow -- npx -y mcp-remote https://mcp.example.com/mcp) completes OAuth and lists tools. This is
our current workaround.

Live metadata documents (sanitized)

GET /.well-known/oauth-protected-resource → 200:

{"resource":"https://mcp.example.com/mcp","authorization_servers":["https://mcp.example.com/"],"scopes_supported":["mcp","offline_access"],"bearer_methods_supported":["header"]}

GET /.well-known/oauth-authorization-server → 200 (identical at
/.well-known/openid-configuration and both path-suffixed variants):

{
  "issuer": "https://mcp.example.com/",
  "authorization_endpoint": "https://mcp.example.com/oauth/authorize",
  "token_endpoint": "https://mcp.example.com/oauth/token",
  "revocation_endpoint": "https://mcp.example.com/oauth/revoke",
  "jwks_uri": "https://mcp.example.com/.well-known/jwks",
  "grant_types_supported": ["authorization_code", "refresh_token"],
  "response_types_supported": ["code"],
  "response_modes_supported": ["query", "form_post", "fragment"],
  "scopes_supported": ["openid", "offline_access", "mcp"],
  "claims_supported": ["aud", "exp", "iat", "iss", "sub"],
  "id_token_signing_alg_values_supported": ["RS256"],
  "code_challenge_methods_supported": ["plain", "S256"],
  "subject_types_supported": ["public"],
  "prompt_values_supported": ["consent", "login", "none", "select_account"],
  "token_endpoint_auth_methods_supported": ["none", "client_secret_basic", "client_secret_post", "private_key_jwt"],
  "revocation_endpoint_auth_methods_supported": ["client_secret_post", "private_key_jwt", "client_secret_basic"],
  "require_pushed_authorization_requests": false,
  "tls_client_certificate_bound_access_tokens": false,
  "registration_endpoint": "https://mcp.example.com/oauth/register",
  "claims_parameter_supported": false,
  "request_parameter_supported": false,
  "request_uri_parameter_supported": false,
  "authorization_response_iss_parameter_supported": false,
  "authorization_response_iss_parameter_supported_NOTE": "false is a WORKAROUND for the second bug below; the server actually sends iss. It was true when that bug reproduced."
}

(The _NOTE key is annotation for this issue, not part of the live document.)

Second defect: RFC 9207 iss is dropped when relaying the OAuth callback

Found while debugging on Linux, where the flow gets further. With
authorization_response_iss_parameter_supported: true advertised (the honest value),
codex mcp login on Linux failed at the callback stage:

Error: failed to handle OAuth callback

Caused by:
    Authorization server response missing required issuer: expected https://mcp.example.com/

Evidence the server sends iss correctly — raw callback captured with a local listener
(DCR probe client, browser completed the redirect):

GET /cb?code=…&state=…&iss=https%3A%2F%2Fmcp.example.com%2F HTTP/1.1

Byte-exact match with the advertised issuer. Cause, from the codex source
(codex-rs/rmcp-client/src/perform_oauth_login.rs): the local callback server extracts
only code and state (OauthCallbackResult { code, state }) and calls
oauth_state.handle_callback(&code, &csrf_state) — the variant without issuer.
rmcp 1.8.0 (validate_authorization_response_issuer) then requires iss because the
AS metadata advertises support → guaranteed failure against any server that honestly
advertises RFC 9207. Codex discards the very parameter rmcp then demands.

Suggested fix: extract iss from the callback query and use
handle_callback_with_issuer / handle_callback_url.

Current server-side workaround (required for codex to work at all): advertise
authorization_response_iss_parameter_supported: false while still sending iss.

Expected behavior

  1. macOS: the OAuth flow proceeds as it does on Linux — or the error names the actual
    failing step instead of No authorization support detected after three successful
    discovery responses.
  2. The callback relay preserves iss so servers can honestly advertise RFC 9207.

Activity

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 CLIbugSomething 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