--- title: "Claude Code Won't Log In (Warp & iTerm2) — Corrupt Keychain Credential" domain: troubleshooting category: claude-code tags: [claude-code, authentication, oauth, keychain, macos, warp, iterm2] status: published created: 2026-06-09 updated: 2026-06-09 --- # Claude Code Won't Log In (Warp & iTerm2) — Corrupt Keychain Credential ## Symptom Claude Code (v2.1.169) would not log in from Warp. The login flow never completed. The same failure occurred in iTerm2, which ruled out a terminal-specific cause. ## Investigation path 1. **Version** — `claude --version` = 2.1.169. Already well past the v2.1.105–2.1.107 bracketed-paste regression (fixed in 2.1.108), so the known paste bug was not it. 2. **Environment / overrides** — none of `ANTHROPIC_API_KEY`, `CLAUDE_CODE_OAUTH_TOKEN`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_BASE_URL`, or `CLAUDE_CODE_PATH` were set, so no stale key or shim was hijacking auth. System clock was correct (rules out token-time skew). 3. **Account record** — `~/.claude.json` had `oauthAccount` and `userID` populated (`maj.linux@gmail.com`), i.e. Claude Code believed it already had an account. 4. **Keychain** — a `Claude Code-credentials` generic-password item existed, but `security find-generic-password -s "Claude Code-credentials" -w` returned an **empty / non-JSON payload** (failed to parse). The credential entry was present but its secret was empty/corrupt. ## Root cause A **corrupt (empty) Keychain credential** named `Claude Code-credentials`. Claude Code saw an existing credential, tried to read/refresh it, failed to parse it, and wedged *before* it could start a clean login. Because the account also existed in `~/.claude.json`, the CLI kept trying to use the broken credential instead of prompting fresh auth. This is system-level (Keychain), which is why it reproduced across both Warp and iTerm2. ## The fix ```bash # 1. Remove the broken credential security delete-generic-password -s "Claude Code-credentials" # 2. Re-authenticate claude # then /login, or: claude /login ``` If `/login` still hangs after that, also clear the stale account record and retry: ```bash cp ~/.claude.json ~/.claude.json.bak python3 -c "import json,pathlib; f=pathlib.Path.home()/'.claude.json'; d=json.load(open(f)); d.pop('oauthAccount',None); json.dump(d,open(f,'w'),indent=2)" claude /login ``` Resolved on step 1+2 — login succeeded after deleting the corrupt Keychain item. ## Notes - On macOS, Claude Code credentials live in the **login Keychain** (`Claude Code-credentials`), not in `~/.claude/.credentials.json` (that path is Linux/other). - Quick triage command to spot the same failure again: ```bash security find-generic-password -s "Claude Code-credentials" -w | python3 -m json.tool ``` If that errors with "Expecting value", the stored secret is empty/corrupt — delete and re-login. ## Related - Config: `~/.claude.json` (oauthAccount, userID), login Keychain item `Claude Code-credentials` - Other Claude Code note: `claude-mem-setting-sources-empty-arg.md`