[BUG] MACOS Keychain: argv fallback for oversized OAuth credential payload (>4KB) itself fails silently ("pbt" error) during MCP OAuth login

Status Open
Reported on v2.1.69
Maintainer reply None cached
Activity 0 comments · opened Sep 8, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Authenticating an MCP server via OAuth (claude mcp add + /mcp login) on macOS fails to persist credentials to Keychain when the serialized credential blob exceeds macOS's security -i 4096-byte stdin line-buffer limit — even though the fallback path that's supposed to handle exactly this case (passing the payload via argv instead of stdin, per the fix shipped for #30337 in 2.1.69) is itself broken for this payload size.

The full browser-based OAuth exchange (authorization code + PKCE) with the identity provider (AWS Cognito, OIDC) completes successfully — login page shows "Login successful, close the window" — but back in the CLI, the server still shows as unauthenticated. No error is shown in the normal (non-debug) UI; the only visibility is --debug-file, which shows the WARN about the oversized payload followed by a terse, non-actionable Error during auth completion: pbt.

This means any MCP OAuth integration whose combined discovery-metadata + token payload exceeds ~4KB is currently unusable, regardless of how correctly the identity provider and MCP server are configured — the failure is entirely inside Claude Code's local credential-persistence step, which runs after the OAuth exchange has already succeeded.

What Should Happen?

Credentials should persist successfully regardless of payload size (well within this machine's ARG_MAX of 1,048,576 bytes, confirmed via getconf ARG_MAX — the 7.3KB payload here is nowhere near that ceiling, so the argv fallback has ample room and its failure is a bug, not a hard limit). At minimum, a real, actionable error should surface in the non-debug UI instead of a silent "still unauthenticated" state.

Error Messages/Logs

[DEBUG] MCP server "<name>": Opening authorization URL: https://<idp-host>/oauth2/authorize?response_type=code&client_id=<client_id>&code_challenge=[REDACTED]&code_challenge_method=S256&redirect_uri=http%3A%2F%2Flocalhost%3A<port>%2Fcallback&state=[REDACTED]&scope=openid+email+profile&resource=https%3A%2F%2F<redacted-host>%2Fmcp
[DEBUG] MCP server "<name>": Initial auth result: REDIRECT
[DEBUG] MCP server "<name>": MCP OAuth server cleaned up
[DEBUG] MCP server "<name>": Completing auth flow with authorization code
[DEBUG] MCP server "<name>": Returning cached discovery state (authServer: https://<idp-issuer>)
[DEBUG] MCP server "<name>": Saving discovery state (authServer: https://<idp-issuer>)
[WARN] Keychain payload (7333B JSON) exceeds security -i stdin limit; using argv
[DEBUG] MCP server "<name>": Using pre-configured client ID
[DEBUG] MCP server "<name>": Returning code verifier
[DEBUG] MCP server "<name>": Using pre-configured client ID
[WARN] Keychain payload (7347B JSON) exceeds security -i stdin limit; using argv
[DEBUG] MCP server "<name>": Invalidated credentials (scope: tokens)
[DEBUG] MCP server "<name>": Returning cached discovery state (authServer: https://<idp-issuer>)
[DEBUG] MCP server "<name>": Saving discovery state (authServer: https://<idp-issuer>)
[WARN] Keychain payload (7347B JSON) exceeds security -i stdin limit; using argv
[DEBUG] MCP server "<name>": Using pre-configured client ID
[DEBUG] MCP server "<name>": Returning code verifier
[DEBUG] MCP server "<name>": Using pre-configured client ID
[DEBUG] MCP server "<name>": Error during auth completion: pbt

(Server name, host, issuer, and client ID redacted — internal identifiers, not needed to reproduce the bug. Identity provider is AWS Cognito/OIDC.)

Verified directly (not assumed) on the affected machine:
- `man security` — `-i` is documented only as "run in interactive mode... read from stdin"; no buffer-size flag or equivalent tunable exists.
- `getconf ARG_MAX` → `1048576` (1 MB) — the argv fallback is not constrained by an OS argument-size ceiling at 7KB.

Steps to Reproduce

  1. Add a remote HTTP MCP server backed by an OAuth-protected resource, using a pre-registered (non-DCR) client, against an identity provider that returns a full OIDC discovery document (issuer, all endpoint URLs, supported scopes/algorithms) plus RFC 9728 protected-resource metadata — e.g. AWS Cognito:

claude mcp add --transport http --client-id <client_id> --callback-port <port> <name> <mcp-url>

  1. Run with --debug-file <path> (or trigger auth via /mcp in an interactive session) and complete the browser login flow. The browser shows Claude Code's local callback success page.
  2. Back in the CLI, the server still shows as unauthenticated — no error in the normal UI.
  3. In the debug log: the token exchange completes ("Completing auth flow with authorization code"), then a [WARN] Keychain payload (NNNN B JSON) exceeds security -i stdin limit; using argv appears, followed shortly by Error during auth completion: pbt.

Note: the credential blob is large here specifically because it bundles the full OIDC discovery document + RFC 9728 metadata + access/ID/refresh tokens + PKCE bookkeeping into a single JSON entry for one MCP server (see "Saving discovery state" / "Returning code verifier" / "Using pre-configured client ID" in the log) — not a misconfiguration on the IdP or MCP-server side. Any of these fields alone is small; combined they reach ~7.3KB, well over the 4096-byte security -i line limit that #28901/#30337 already documented, but this time hitting the argv fallback's own bug rather than the original stdin limit.

Claude Model

None

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.224

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Warp

Additional Information

  • Related issues (both closed + locked, so filing new rather than commenting): #28901, #30337. #30337 was closed as fixed in 2.1.69: "Fixed macOS keychain corruption when using multiple OAuth MCP servers. Large OAuth metadata blobs could overflow the security -i stdin buffer, silently leaving stale credentials behind and causing repeated /login prompts" — this report shows that fix's argv fallback still fails for a ~7.3KB payload.
  • Workaround: running claude from a Linux environment (container/WSL/remote host) avoids this entirely, since Linux's credential-storage backend doesn't go through macOS's security CLI.
  • Suggested fix directions:
  1. Fix whatever is producing the truncated pbt error in the argv-fallback path (payloads this size are well within ARG_MAX).
  2. Don't bundle the full OIDC discovery document into the same Keychain entry as the tokens — cache it separately, keyed by issuer (the log's "Returning cached discovery state" suggests this caching already exists elsewhere), which would shrink most payloads back under 4096B and avoid the argv path entirely.
  3. Surface a real, actionable error in the non-debug UI when credential persistence fails, instead of a silent "still unauthenticated" state.

View original on GitHub ↗