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

Open 💬 10 comments Opened Jul 22, 2026 by mike-phys08
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

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.

  1. The callback relay preserves iss so servers can honestly advertise RFC 9207.

View original on GitHub ↗

10 Comments

github-actions[bot] contributor · 1 month ago

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

  • #34427

Powered by Codex Action

jeet23 · 1 month ago

Facing the same problem with iss being discarded and OAuth login fails.

Error: failed to handle OAuth callback

Caused by:
    Authorization server response missing required issuer: ...

This started after updating to Codex 0.145.0. It was working fine until 0.142.0.

It seems to be related to this PR had bumped the rmcp version.

bbingz · 1 month ago

Analysis (community)

Thank you for the unusually high-signal report — nginx access logs, Linux control, same-Mac mcp-remote control, and the live metadata documents make this much easier to reason about than most OAuth failures.

  • Environment / versions (from the report): codex-cli 0.144.6 (rmcp 1.8.0), macOS arm64 (official codex-aarch64-apple-darwin binary + fresh CODEX_HOME); Linux x86_64 control succeeds against the same server. I did not re-run the live macOS repro myself; analysis below is static reading of current main plus the evidence already in this thread / related issues.
  • Repro status: partially confirmed from source + report — the callback/iss path is a clear code defect; the macOS pre-flow collapse is a strong stack-divergence hypothesis consistent with the logs, but the exact soft-fail mode on the login HTTP client is inferred, not packet-captured.
  • Observed vs expected:
  • macOS: GET /mcp 401 → protected-resource 200 → AS metadata 200, then no POST /oauth/register, CLI surfaces Error: No authorization support detected.
  • mcp add nuance: prints Detected OAuth support. Starting OAuth flow… then the same error — capability detection and the login flow are not the same HTTP stack (see below).
  • Linux: reaches DCR + authorize; with honest authorization_response_iss_parameter_supported: true, fails later with Authorization server response missing required issuer despite iss= present on the redirect.
  • Expected: discovery that already returned 200 AS metadata should continue (or name the real client-side failure); callback relay should preserve RFC 9207 iss when the AS requires it.

Related: same opaque error class on Linear in #34427; earlier macOS MCP OAuth TLS/native-tls direction in #18772.

Root-cause hypothesis

Two separable defects; either alone is enough to break a subset of servers, and together they match this report’s Linux-vs-macOS split.

(1) Pre-flow macOS: discovery soft-fails to NoAuthorizationSupport (medium confidence)

On current main, capability detection and login re-discovery use different clients:

| Path | Where | HTTP client |
|---|---|---|
| “Detected OAuth support” / oauth_login_support | codex-mcpdiscover_streamable_http_oauth | Direct reqwest 0.13 + rustls-only features in rmcp-client/Cargo.toml, with no_proxy() (auth_status.rs, comment cites system-configuration / #8912) |
| Actual perform_oauth_login | OauthLoginFlow::new | OAuthHttpClientAdapter over exec-server ReqwestHttpClient (perform_oauth_login.rs defaults to Arc::new(ReqwestHttpClient)), workspace reqwest 0.12 + cookie store; build_reqwest_client_with_custom_ca only forces use_rustls_tls() when a custom CA is configured |

That split matches the report’s “Detected OAuth support … then No authorization support detected” pattern: detection can succeed on the rustls/no_proxy path while login re-runs discovery on the adapter stack and fails client-side.

rmcp 1.8.0 then collapses several real failures into one user-facing error: transport errors / unparseable AS bodies tend to soft-fail into “no metadata,” and discover_metadata surfaces AuthError::NoAuthorizationSupport (“No authorization support detected”). From the outside that is indistinguishable from a server that truly lacks OAuth — which is exactly the opaque failure after three nginx 401/200/200 lines.

**What is not proven without a live capture of OAuthHttpClientAdapter status/body:** whether this reporter’s server fails via empty body, parse failure, mid-stream reassembly, TLS backend differences, or something else on macOS. The dual-stack + soft-fail story is the best fit for the existing evidence; TLS 1.3-only cases in #18772 are one concrete historical instance of the same error string, not necessarily this server’s cause.

(2) Callback bug: iss dropped (high confidence)

Confirmed in codex-rs/rmcp-client/src/perform_oauth_login.rs:

  • OauthCallbackResult holds only { code, state }.
  • parse_oauth_callback matches code / state / error / error_description and ignores iss.
  • finish() calls oauth_state.handle_callback(&code, &csrf_state) — the no-issuer API.

When AS metadata advertises authorization_response_iss_parameter_supported: true, rmcp’s validate_authorization_response_issuer requires iss. The browser redirect can include a correct iss= (as captured in the issue), but Codex never forwards it → Authorization server response missing required issuer. That matches the Linux failure and the server-side workaround of advertising false while still sending iss. Timing aligns with the rmcp 1.8.0 bump (#29634) relative to older 1.7.x pins.

High-level fix outline (not a PR)

Keep the change small and layered; no need to touch credential store, DCR policy, unrelated MCP transport, or broad rmcp API rewrites.

  1. Callback / RFC 9207 (Defect A)

Extend OauthCallbackResult with Option<String> issuer; parse iss from the callback query; call handle_callback_with_issuer (or handle_callback_url with the full URL) when present. Prefer fixing the client over asking every AS to lie about authorization_response_iss_parameter_supported.

  1. Unify login HTTP with discovery (Defect B)

Prefer explicit rustls (and the same no_proxy policy discovery already uses for #8912) on the login / ReqwestHttpClient / OAuth adapter path — or reuse one shared client construction so macOS does not depend on a different TLS/proxy stack for MCP OAuth only. Aligning with the direction discussed in #18772 without expanding scope to all exec-server HTTP.

  1. Observability

When discovery HTTP is non-success at the client, or a 200 body fails to parse, map to a concrete error (URL + status + parse/transport reason) instead of only NoAuthorizationSupport. Ensure RUST_LOG actually surfaces adapter errors (the report’s RUST_LOG=debug producing nothing past the opaque error is itself a product bug).

Optional upstream: ask rmcp to reduce soft-fail opacity — but Codex can fix iss and client unification independently.

Non-goals: server workarounds as the long-term fix; rewriting MCP transports; changing how credentials are stored.

Test ideas

Failing-first coverage the team (or an invitee) could land with the fix:

  • Unit — callback: parse_oauth_callback("/callback/<id>?code=c&state=s&iss=https%3A%2F%2Fas.example%2F", …) yields issuer; finish/mock path invokes handle_callback_with_issuer (or equivalent) with that value; absent iss still succeeds when the AS does not require it.
  • Unit/integration — adapter: mock HttpClient streams a 200 RFC 8414 JSON body; assert the reassembled HttpResponse bytes reach rmcp intact; empty body after 200 must not silently become “no auth” once codex maps errors explicitly.
  • Regression: hermetic local AS (e.g. axum) with authorization_response_iss_parameter_supported: true + redirect including iss completes login.
  • Optional policy assert: login client builder uses rustls/no_proxy consistent with auth_status discovery.

Questions for maintainers

Happy to be corrected on any of this — a few alignment checks only:

  1. Is unifying the login path onto the same rustls + no_proxy construction as auth_status discovery the preferred direction, or do you want a narrower adapter-only fix?
  2. Should Defect B (opaque discovery / dual HTTP stacks) be tracked separately from Defect A (iss relay), as the reporter offered?
  3. Is #34427 likely the same soft-masked discovery class with a different underlying transport cause (e.g. CA / container), or something you already know is distinct?
  4. Any objection to mapping soft-failed metadata fetch to a concrete error string in codex even before/without an rmcp upstream change?

Happy to refine this analysis with more pointers or a cleaner minimal outline if useful. If the team later wants an invited PR for the small layered approach above, I’d be glad to help — no rush and no expectation.

bbingz · 1 month ago

Building on the root-cause analysis above with the latent introducing commit, one naming/construction correction, and a Defect B status re-check. Traced against main as of 5dd992a (2026-07-24).

Latent introducing PR (the iss-drop predates the #29634 activation noted above). git log --diff-filter=A -- codex-rs/rmcp-client/src/perform_oauth_login.rs returns 1d17ca1fa / #4517 (2025-10-03, "[MCP] Add support for MCP Oauth credentials"), which created perform_oauth_login.rs (141 lines) and oauth.rs (822 lines) with the iss-dropping OauthCallbackResult { code, state } shape already in place. It was latent then because the issuer-enforcing rmcp version was not yet in play; it went active with the rmcp 1.8.0 bump (#29634) already cited above. So the drop is a 9-month-old structural choice, not something introduced by the 1.8.0 bump.

Naming/construction correction - the login HTTP client was restructured post-issue, in two steps. #35023 (1ee8f49, 2026-07-23, "Route exec-server HTTP through configured proxy policy") wired login through HttpClientFactory::new(OutboundProxyPolicy::ReqwestDefault) while still named ReqwestHttpClient (it changed ReqwestHttpClient -> ReqwestHttpClient::new(HttpClientFactory::new(OutboundProxyPolicy::ReqwestDefault))). #35059 (09241ae, 2026-07-24, "Decouple exec-server HTTP from reqwest types") then renamed ReqwestHttpClient -> RouteAwareHttpClient. The current login path is RouteAwareHttpClient::new(HttpClientFactory::new(OutboundProxyPolicy::ReqwestDefault)) (perform_oauth_login.rs:165, 216); codex still calls the no-issuer handle_callback(&code, &csrf_state) (:612). Any fix touching the login HTTP path should target the renamed type.

Defect B status re-check (proxy-policy asymmetry, medium confidence, unremediated as of 5dd992a). Discovery uses Client::builder().timeout(DISCOVERY_TIMEOUT).no_proxy() (auth_status.rs:237-239, comment cites the system-configuration crate bug / #8912); login uses OutboundProxyPolicy::ReqwestDefault, which lets reqwest own proxy selection and does not call no_proxy() as discovery does. This is a real asymmetry in codex's own source. What I could not confirm from source alone is whether this path actually exercises the system-configuration behavior or contributes to the OP's failure - that is runtime-dependent (system proxy configuration + the system-configuration crate's behavior), so I hold this at medium confidence, not "confirmed." The discovery-vs-login client split noted in the first comment is also still present and unremediated: discovery uses rmcp-client's pinned reqwest = "0.13" (rustls-only, rmcp-client/Cargo.toml:33), while the login client uses the workspace http-client crate's reqwest - a separate stack - without overclaiming either causes the OP failure.

Caveat carried forward: rmcp 1.8.0's source is not in this machine's cargo cache, so I did not re-verify the exact rmcp-side method/error behavior; the codex-side facts above (OauthCallbackResult shape, handle_callback call, no_proxy asymmetry, reqwest split) are from codex's own tree.

geauxtigers · 29 days ago

I can reproduce the RFC 9207 issuer-callback failure with Render’s official hosted MCP server on Windows.

Environment:

codex mcp add render --url https://mcp.render.com/mcp --oauth-client-id codex

Browser authorization completes normally, Codex returns:

Error: failed to handle OAuth callback

Caused by:
Authorization server response missing required issuer: expected https://api.render.com

rodjac-lab · 29 days ago

I can also reproduce the RFC 9207 issuer-callback failure on Linux with Sentry’s official hosted MCP server.

Environment:

  • Codex CLI: 0.146.0 (also reproduced on 0.145.0)
  • Install: official standalone linux-x86_64 build
  • OS: Fedora 44 x86_64
  • MCP server: https://mcp.sentry.dev/mcp/<org>
  • No proxy environment variables

codex mcp login sentry successfully discovers OAuth, opens Sentry’s authorization page, and Sentry accepts the consent. After the browser redirects to Codex’s local callback, the CLI fails with:

Error: failed to handle OAuth callback

Caused by:
    Authorization server response missing required issuer: expected https://mcp.sentry.dev

As a same-machine control, native OAuth login completed successfully for the official hosted Supabase and Vercel MCP servers immediately before this test. This rules out a general browser callback, localhost listener, or machine-level OAuth failure.

So the iss relay defect is not limited to the self-hosted server in the original report, macOS, or Windows/Render: it also affects Codex 0.146.0 on Linux against Sentry’s official MCP service.

ahnaineh · 26 days ago

Independent reproduction of the RFC 9207 callback defect with another authorization-server implementation:

  • Codex CLI: 0.146.0
  • OS: Linux x86_64
  • MCP/OAuth server: FastMCP 4.0.0b1, local Streamable HTTP at http://localhost:8001/mcp
  • AS metadata issuer: http://localhost:8001/
  • Initial metadata: authorization_response_iss_parameter_supported: true

The flow completed discovery, DCR (POST /register → 201), authorization/consent, the upstream token exchange, and the FastMCP IdP callback (GET /auth/callback?... → 302). Codex then failed with:

Error: failed to handle OAuth callback

Caused by:
    Authorization server response missing required issuer: expected http://localhost:8001/

FastMCP 4.0.0b1 builds that final client redirect with build_client_redirect(..., iss=str(self.issuer_url)); a focused regression check confirms the generated callback URL carries the issuer byte-for-byte matching discovery.

As the temporary server-side workaround, changing only the advertised metadata field to authorization_response_iss_parameter_supported: false (while continuing to emit iss) makes the discovery document Codex-compatible. This adds a localhost/FastMCP control to the OpenIddict, Render, and Sentry cases already reported above.

Cliffinkent · 25 days ago

Confirmed this also affects Sentry's hosted MCP server on macOS, codex-cli 0.146.0.

Command:

codex mcp login sentry

Browser authorisation completed and returned to the local callback, then Codex failed with:

Error: failed to handle OAuth callback

Caused by:
Authorization server response missing required issuer: expected https://mcp.sentry.dev

MCP config: https://mcp.sentry.dev/mcp

Afterwards, codex mcp list showed Sentry as enabled but with Auth: Unsupported.

This suggests the callback issuer-handling defect also affects Sentry's production MCP service and is still present in 0.146.0.

patrikduksin · 24 days ago

anyone checking on that, they fixed it in 0.147.0-alpha.1.2, so wait a bit till release or install alpha and you are good to go

bbingz · 22 days ago

Confirming @patrikduksin's report with the exact changes, since two separable defects were in play here and only one is what most people in this thread are hitting.

Defect A (the RFC 9207 iss drop) is fixed on main in 61de0d8fe / #35720 (2026-07-28, shipped in the 0.147.0 alphas). OauthCallbackResult now carries issuer: Option<String> (codex-rs/rmcp-client/src/perform_oauth_login.rs:293-296), parse_oauth_callback reads "iss" (:339), and finish() calls handle_callback_with_issuer(&code, &csrf_state, issuer.as_deref()) (:613) instead of the no-issuer API. Regression coverage landed with it: parse_oauth_callback_preserves_rfc_9207_issuer (:1015) and oauth_callback_validates_rfc_9207_issuer_before_token_exchange (:863). That is precisely the failure @ahnaineh saw against FastMCP 4.0.0b1 and @Cliffinkent saw against mcp.sentry.dev — both worth retesting on 0.147.0-alpha.1.2 or later, and any AS advertising authorization_response_iss_parameter_supported: false purely as a workaround can stop doing that.

Defect B (discovery and login on different HTTP stacks) — the likely source of the OP's macOS No authorization support detected — was addressed separately by #35806 (9ea975a2d) and #35814 (709283b43): callers must now pass an HTTP client into MCP OAuth discovery and login, and the separate direct reqwest path is gone. auth_status.rs takes http_client: Arc<dyn HttpClient> (:87, :199, :219) rather than building its own no_proxy() client, so the asymmetry I flagged no longer exists in source.

I have not re-run the original macOS repro, so @mike-phys08's pre-flow case is the one still worth verifying on 0.147.0+ before this is closed. One item from the outline does not appear to be covered by either PR: mapping a soft-failed metadata fetch to a concrete error (URL + status + parse/transport reason) instead of collapsing to NoAuthorizationSupport. If that is wanted as a follow-up I am happy to help when invited.