Troubleshooting

Atlas: OAuth state mismatch, potential CSRF attack

Updated 6 min read

Atlas rejects the MCP OAuth callback with "OAuth state mismatch - potential CSRF attack" because the state parameter returned by the authorization server does not match the state Atlas generated for the pending OAuth flow, so the callback handler refuses to exchange the code and the server stays in needs_auth. Fix it by closing stale browser tabs from an earlier `atlas mcp auth` attempt and re-running `atlas mcp auth <name>` in one pass without reusing an old authorization URL.

Why does Atlas report OAuth state mismatch

Atlas reports "OAuth state mismatch - potential CSRF attack" when the state parameter returned by the authorization server does not match the state Atlas generated for the pending OAuth flow. Only 1 flow at a time holds a valid state, so the callback handler refuses to exchange the code and the MCP server stays in needs_auth.

The state parameter is a one-time value that ties a callback to the exact login Atlas started. Atlas generates it, sends it out with the authorization request, and checks it when the callback lands. A mismatch means the callback belongs to some other flow, and Atlas refuses to trade the code for a token rather than trusting it. The wording is blunt on purpose: a state mismatch is what a cross-site request forgery attempt looks like. Almost always the real cause is far more mundane, a leftover browser tab from an earlier `atlas mcp auth` attempt whose state is no longer the current one.

How to fix an OAuth state mismatch in Atlas

Fix the Atlas OAuth state mismatch in 4 steps: close every stale browser tab from an earlier `atlas mcp auth` attempt, re-run `atlas mcp auth <name>` and complete the flow in one pass, set an explicit `redirectUri` if a proxy rewrites query strings, and confirm no other local service holds the callback port.

Start with the browser. Only the newest Atlas flow has a valid state, so any tab left open from a previous attempt is carrying a state Atlas will now reject. Close all of them, then run `atlas mcp auth <name>` fresh and walk through consent without pausing, without going back, and without opening an old authorization URL from your history. Completing the flow in one pass is the single most reliable fix. If a mismatch survives a clean run, the state is being altered in transit and you move on to the proxy and callback port causes.

How a corporate proxy causes an Atlas OAuth state mismatch

A corporate proxy can cause an Atlas OAuth state mismatch by rewriting query strings on the callback URL. When the state parameter is stripped or altered in transit, the value that reaches Atlas is no longer the state Atlas generated, and setting an explicit `redirectUri` on that server's oauth config is the 1 documented fix.

Setting an explicit `redirectUri` on that server's oauth config is the documented fix in Atlas. A fixed, known redirect gives the proxy and the authorization server one agreed target instead of a value assembled on the fly, which removes the rewriting opportunity. The signature of this cause is a state mismatch that reproduces every single time, on a clean flow, with no stale tabs anywhere. Ordinary stale-tab mismatches are intermittent and disappear once you run the flow in one pass. A deterministic mismatch on a corporate network points at the network path.

Check whether another service is holding the Atlas OAuth callback port

Confirm the Atlas OAuth callback port is not being intercepted by another local service. When a 2nd process answers on that port, the callback never reaches Atlas with the state it generated, the pending flow for that MCP server never completes, and the status stays at needs_auth.

Port collisions are common on developer machines running several tools at once, and the symptom is easy to misread as an Atlas bug. Check what is listening on the callback port before assuming the OAuth flow is broken. The Atlas oauth config block for an MCP server accepts callbackPort and redirectUri alongside clientId, so moving Atlas to an uncontested port is a config change on that server entry rather than a fight with the other service. Be aware of the caveat: if the authorization server pre-registered a specific redirect, changing the port on the Atlas side means updating the registered redirect too.

How to verify the MCP OAuth flow completed in Atlas

Verify the Atlas MCP OAuth flow by running `atlas mcp` after consent and reading 1 line, the status row for that server. A server that completed the exchange leaves needs_auth and reaches connected. A row still sitting at needs_auth means the callback was rejected again and the state mismatch is unresolved.

`atlas mcp` is the authoritative check because the status row is written by the same code path that refused the exchange. Do not judge success by the browser page, which can show a friendly confirmation while Atlas rejected the callback moments later. If the row still reads needs_auth, work back through the causes in order: stale tabs first, then a proxy rewriting the callback query string, then a callback port held by another local service. Once the row reads connected, that MCP server's tools are exposed to the agent again.

How to fix it

  1. 01Close any stale browser tabs from an earlier `atlas mcp auth` attempt; only the newest flow has a valid state.
  2. 02Re-run `atlas mcp auth <name>` and complete the flow in one pass without reusing an old authorization URL.
  3. 03If a corporate proxy rewrites query strings on the callback URL, set an explicit `redirectUri` on the server's oauth config.
  4. 04Confirm the callback port is not being intercepted by another local service.

Frequently asked questions

What does "OAuth state mismatch - potential CSRF attack" mean in Atlas?
It means the state parameter returned by the authorization server does not match the state Atlas generated for the pending OAuth flow, so the callback handler refuses to exchange the authorization code and the MCP server stays in needs_auth.
How do I fix an MCP OAuth state mismatch in Atlas?
Close stale browser tabs from any earlier `atlas mcp auth` attempt, then re-run `atlas mcp auth <name>` and complete the flow in one pass without reusing an old authorization URL. Only the newest flow has a valid state.
Am I actually under a CSRF attack when Atlas says this?
Usually not. The message is worded that way because a state mismatch is what CSRF looks like, but the common cause is a leftover browser tab from an earlier `atlas mcp auth` attempt carrying an old state.
Can a corporate proxy break the Atlas OAuth callback?
Yes. A proxy that rewrites query strings on the callback URL can alter the state parameter in transit. Set an explicit `redirectUri` on that server's oauth config so the redirect target is fixed and known.
Why does my MCP server stay in needs_auth after the OAuth state mismatch?
Because the Atlas callback handler refused to exchange the code, no token was ever obtained. The server therefore remains at needs_auth until an OAuth flow completes with a matching state.
Does the callback port matter for atlas mcp auth?
Yes. If another local service intercepts the callback port, the callback never reaches Atlas. Confirm nothing else is listening on it. The Atlas oauth config accepts callbackPort and redirectUri on the server entry.
Can I reuse an old authorization URL for atlas mcp auth?
No. An old authorization URL carries a state from a previous flow, which Atlas will reject. Re-run `atlas mcp auth <name>` and complete the fresh flow in one pass.

Try Atlas in your terminal

The terminal-native AI coding agent. Free core, single binary.

Install Atlas

Related guides

Atlas with GLM-4.5-Air: The 106B Self-Hostable Cheap Slot in 2026

GLM-4.5-Air drives Atlas at $0.20 per Mtok input and $1.10 per Mtok output on a 128K tokens (131,072) window. A 106B total / 12B active MIT-licensed MoE.

Atlas vs Codebuff: Terminal AI Coding Agents in 2026

Atlas and Codebuff are terminal AI coding agents for 2026. Compare Atlas's terminal-native TUI, permission-gated tools, and diff review with Codebuff's multi-agent system and flexible pricing.

Atlas with Mixtral 8x22B: The Largest Open MoE of Its Era in 2026

Mixtral 8x22B scaled the MoE idea in April 2024: 64,000 tokens at $2.00 / 1M input tokens and $6.00 / 1M output tokens. Atlas setup, self-hosting, and honest limits.

Atlas with Kimi K2.7 Code: Open Weights at Trillion-Parameter Scale (2026)

Kimi K2.7 Code drives Atlas at $0.95 / $4 per Mtok on a 262,144 token window. Open weights, 1T total parameters, served by four independent providers.

Atlas with Qwen3.5 Plus: A Million-Token Window for $0.40 per Mtok in 2026

Qwen3.5 Plus gives Atlas a 1M tokens (1,000,000) context window at $0.40 per Mtok input and $2.40 per Mtok output. What the million tokens buy, and what closed weights cost.

Atlas with Ministral 3B: The $0.04 Housekeeping Model in 2026

Ministral 3B is the cheapest model Mistral sells: $0.04 / 1M input tokens and $0.04 / 1M output tokens across 128,000 tokens. Atlas small_model setup and limits.

Atlas with Devstral Medium (2507): Agent-Trained Frontier Coding in 2026

Devstral Medium (2507) gives Atlas agent-first training at $0.40 / 1M input tokens and $2.00 / 1M output tokens, with 128,000 tokens in and out. Setup and tradeoffs.

Atlas with GLM-4.6: 200K Open Weights at the 4.5 Price in 2026

GLM-4.6 runs Atlas on a 200K tokens (204,800) context at $0.60 per Mtok input and $2.20 per Mtok output, the same price GLM-4.5 charged on a 128K window.

Browse this resource hub