CLAUDE LABJP
FORK — Claude Code 2.1.212 changes what /fork does: it copies your conversation into a new background session with its own row in claude agents, so you can keep working. The old in-session subagent is now /subtaskLIMITS — WebSearch calls are now capped at 200 per session by default, and subagent spawns get the same 200 ceiling, so a runaway search or delegation loop stops on its ownMCPBG — MCP tool calls running past two minutes now move to the background automatically, keeping the session usable. Tune the threshold with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MSPLANFIX — Fixed plan mode auto-running file-modifying Bash commands such as touch and rm without a permission prompt or an SDK canUseTool callbackSONNET5 — Claude Sonnet 5 is running on introductory pricing of $2 per million input tokens and $10 per million output. After August 31 it moves to $3 and $15IPO — Bankers are reportedly lining up investor meetings for Anthropic ahead of a possible public listing as soon as OctoberFORK — Claude Code 2.1.212 changes what /fork does: it copies your conversation into a new background session with its own row in claude agents, so you can keep working. The old in-session subagent is now /subtaskLIMITS — WebSearch calls are now capped at 200 per session by default, and subagent spawns get the same 200 ceiling, so a runaway search or delegation loop stops on its ownMCPBG — MCP tool calls running past two minutes now move to the background automatically, keeping the session usable. Tune the threshold with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MSPLANFIX — Fixed plan mode auto-running file-modifying Bash commands such as touch and rm without a permission prompt or an SDK canUseTool callbackSONNET5 — Claude Sonnet 5 is running on introductory pricing of $2 per million input tokens and $10 per million output. After August 31 it moves to $3 and $15IPO — Bankers are reportedly lining up investor meetings for Anthropic ahead of a possible public listing as soon as October
Articles/Claude Code
Claude Code/2026-04-26Intermediate

Untangling Claude Code's 'Authorization Failed' Error — OAuth, MCP, and Dynamic Client Registration

Why Claude Code suddenly throws 'authorization failed' or 'incompatible auth server: does not support dynamic client registration', and what to actually do about it. A practical walkthrough of OAuth, MCP server requirements, and the real fixes that work in production.

Claude Code196OAuth3MCP45AuthorizationDynamic Client RegistrationTroubleshooting11

import { Callout } from '@/components/ui/callout';

If you have been wiring Claude Code to MCP servers lately, you may have hit one of these:

sdk auth failed: incompatible auth server: does not support dynamic client registration

Or the terser version:

authorization failed

The first time I saw it, I assumed I had misconfigured something. After a few rounds of digging, I realized the error is almost always about a mismatch between Claude Code's evolving authentication flow and what the MCP server on the other end actually supports. Here is how I now think about this error, and the steps that reliably resolve it.

What the Error Is Really Saying

Claude Code now uses OAuth 2.1 with Dynamic Client Registration (RFC 7591) when it talks to MCP servers. Dynamic Client Registration lets the MCP client (Claude Code) introduce itself to the server at runtime — no pre-shared client ID, no manual setup. The trade-off is obvious: the MCP server has to actually implement that registration endpoint.

Read the error message again with this in mind:

incompatible auth server: does not support dynamic client registration

That is Claude Code telling you "the server you are pointing me at does not implement runtime registration." Either the server is on an older spec, or it deliberately uses pre-shared credentials.

The Three Common Triggers

After dealing with this across several projects, the failures cluster into three categories.

Trigger 1: Custom or Open-Source MCP Server Does Not Support Dynamic Registration

This is the most common case for in-house or community MCP servers. If /.well-known/oauth-authorization-server does not include a registration_endpoint field — or returns 404 when Claude Code tries to POST to it — Claude Code will refuse to continue.

Trigger 2: SaaS Connector Uses a Custom OAuth Flow

Some SaaS providers ship MCP connectors built around pre-issued client IDs. Slack and Notion's official connectors, for example, are designed to be installed through Cowork rather than wired up by hand in Claude Code. In those cases the error is not a bug; it is a sign you are using the wrong client surface.

Trigger 3: TLS Interception Breaks the Certificate Chain

Inside corporate networks, products like ZScaler or Netskope intercept TLS traffic. If NODE_EXTRA_CA_CERTS is not set, Claude Code cannot validate the auth server's certificate, and the failure surfaces as an authorization error. The console usually has more detail, so always check it before assuming OAuth is the problem.

A Diagnostic Flow You Can Run Top-Down

When the error fires, work through these in order.

Step 1: Run /doctor

Inside a Claude Code session, type /doctor. It surfaces the authentication, network, and MCP connection state in one place. Quite often it pinpoints the issue immediately.

Step 2: Inspect the Well-Known Metadata

curl https://your-mcp-server.example.com/.well-known/oauth-authorization-server | jq .

If registration_endpoint is missing from the response, you have hit Trigger 1.

Step 3: Probe the Registration Endpoint Directly

curl -X POST https://your-mcp-server.example.com/oauth/register \
  -H "Content-Type: application/json" \
  -d '{
    "client_name": "Claude Code Test",
    "redirect_uris": ["http://localhost:54321/callback"]
  }'

A 2xx response means dynamic registration works. Anything else means the endpoint is broken or absent.

Step 4: Add Dynamic Registration to Your MCP Server

If the server is yours, the latest @modelcontextprotocol/sdk for TypeScript has native support. Enable it like this:

import { McpServer } from "@modelcontextprotocol/sdk/server";
 
const server = new McpServer({
  name: "my-mcp-server",
  version: "1.0.0",
  oauth: {
    enabled: true,
    dynamicRegistration: true,
    registrationEndpoint: "/oauth/register",
    authorizationEndpoint: "/oauth/authorize",
    tokenEndpoint: "/oauth/token",
  },
});

Make sure registration_endpoint is also exposed in the well-known document. Once both pieces are in place, Claude Code's complaint disappears.

Step 5: When You Cannot Patch the Server

If the server is a SaaS that you do not control, your realistic options are:

  • Use the official connector through Cowork instead of Claude Code
  • Use Claude in Chrome to interact with the service through the web UI rather than MCP
  • Wrap the API yourself and call it directly from Claude API code

Not every SaaS is a clean fit for Claude Code's MCP flow yet. Check each provider's current docs to see which client surface they support.

Corporate Network Pitfalls

Inside corporate environments, set the CA bundle explicitly:

export NODE_EXTRA_CA_CERTS=/path/to/your/corporate-ca-bundle.pem

Your IT team can supply the bundle path. Restart Claude Code after setting it, and TLS handshakes start succeeding.

Designing for Fewer Errors, Not Just Better Recovery

For the services I run myself, I treat "users never see this error" as the design goal:

  • Test both /.well-known/oauth-authorization-server and the registration endpoint before any deployment
  • Validate Claude Code upgrades in a staging environment before pushing to production
  • Keep an operational runbook that includes a /doctor output template, so on-call rotations move fast when the error does appear

Recovery procedures matter, but engineering away the conditions that cause the error matters more.

Next Step

The next time you see this error, start with /doctor and the well-known metadata. Those two steps cover ninety percent of the cases. The remaining ten percent are usually waiting on a SaaS to ship support, and switching client surfaces is the quickest unblock.

Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

Claude Code2026-06-27
When an OAuth Token Expires, Your Unattended Run Has Nowhere to Go — A Token-Lifecycle Design That Keeps Remote MCP Alive
Remote MCP connectors are authorized via OAuth, but access tokens are short-lived. Interactive sessions can re-authorize in a browser; an unattended scheduled run has nobody to click the dialog. Here is a token-lifecycle design that owns expiry and refreshes ahead of time.
Claude Code2026-05-24
Recovering from Claude Code's 'Tool result could not be submitted'
What 'Tool result could not be submitted' really means in Claude Code, and the practical recovery steps I rely on after years of running indie apps with 50M+ downloads through it.
Claude Code2026-07-18
The MCP Server I Declared Vanished from the List — Designing Config for a Namespace You Share with the Vendor
When a vendor reserves an MCP server name, your .mcp.json declaration goes quiet instead of failing. Here is the preflight check and prefix convention I use to turn that silent gap into a loud stop before an unattended run.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →