If you point Claude Code at DeepSeek V4, OpenRouter, LiteLLM, or another third-party model provider, you may hit Invalid custom3p enterprise config. The message is vague, but it usually means Claude Code could not validate your custom provider settings before sending the first model request.
This guide shows what custom3p means, how Claude Code decides to use it, and how to fix the six most common configuration problems with working examples.
TL;DR
Invalid custom3p enterprise config means Claude Code cannot validate your third-party provider configuration.
custom3p is Claude Code’s internal label for a non-Anthropic API endpoint configured with ANTHROPIC_BASE_URL.
Start with these checks:
- Remove trailing
/v1fromANTHROPIC_BASE_URL. - Use the correct credential variable:
-
ANTHROPIC_AUTH_TOKENfor bearer-token gateways. -
ANTHROPIC_API_KEYforx-api-keygateways.
-
- Validate
~/.claude/settings.json. - Confirm onboarding is completed on fresh installs.
- Make sure your gateway forwards required Claude Code headers.
- Check for managed enterprise policy conflicts.
The trailing /v1 issue is the most common and should be the first thing you fix.
What custom3p means in Claude Code
Claude Code routes requests through different provider modes:
| Mode | How it is triggered |
|---|---|
| Anthropic API | No override set |
| Amazon Bedrock | CLAUDE_CODE_USE_BEDROCK=1 |
| Google Vertex AI | CLAUDE_CODE_USE_VERTEX=1 |
| Microsoft Foundry | CLAUDE_CODE_USE_FOUNDRY=1 |
| Custom third-party |
ANTHROPIC_BASE_URL points to another host |
The last mode is custom3p, short for custom third-party.
When ANTHROPIC_BASE_URL points to OpenRouter, LiteLLM, vLLM, a corporate gateway, or another non-Anthropic endpoint, Claude Code treats it as a custom third-party provider and runs an enterprise-config validation step.
If validation fails, Claude Code returns:
Invalid custom3p enterprise config
This is a configuration validation error, not a policy block.
Why developers are seeing this more often
In April 2026, Anthropic blocked Claude Pro and Max subscription access for third-party agentic tools that were spoofing the Claude Code client ID. Tools like OpenClaw, which routed Claude Code sessions through their own backends, stopped working.
That is separate from this error.
After that change, more developers started using Claude Code’s official third-party provider support to route Claude Code through cheaper model backends. For example, a Reddit thread documented switching the Claude Code agent loop to DeepSeek V4 Pro via OpenRouter, with lower output-token pricing compared with Anthropic API pricing. Projects like DeepClaude packaged this setup behind a CLI workflow.
The problem: Claude Code’s official third-party support is strict. One wrong URL, auth variable, JSON field, or gateway behavior can trigger Invalid custom3p enterprise config.
Root cause 1: ANTHROPIC_BASE_URL includes trailing /v1
Claude Code appends /v1/messages to your base URL.
If your base URL already includes /v1, Claude Code sends requests to:
/v1/v1/messages
That usually returns 404.
Wrong
export ANTHROPIC_BASE_URL="https://api.openrouter.ai/api/v1"
export ANTHROPIC_BASE_URL="https://litellm.yourcompany.com/v1"
Correct
export ANTHROPIC_BASE_URL="https://api.openrouter.ai/api"
export ANTHROPIC_BASE_URL="https://litellm.yourcompany.com"
Verify the endpoint
Run:
curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: Bearer $ANTHROPIC_AUTH_TOKEN" \
"${ANTHROPIC_BASE_URL}/v1/messages" \
-d '{"model":"claude-sonnet-4-6","max_tokens":1,"messages":[{"role":"user","content":"hi"}]}'
Interpret the result:
| Status | Meaning |
|---|---|
200 |
Endpoint exists and request succeeded |
400 |
Endpoint exists, but request body may be invalid |
404 |
Your base URL is probably wrong, often because of /v1
|
Root cause 2: Wrong credential variable
Claude Code supports two auth variables, and they send different headers.
| Variable | Header sent | Use when |
|---|---|---|
ANTHROPIC_API_KEY |
x-api-key |
Gateway expects Anthropic-style API key auth |
ANTHROPIC_AUTH_TOKEN |
Authorization: Bearer |
Gateway expects bearer auth, including most OpenRouter and LiteLLM setups |
OpenRouter example
OpenRouter expects bearer-token auth:
export ANTHROPIC_AUTH_TOKEN="sk-or-your-openrouter-key"
export ANTHROPIC_BASE_URL="https://openrouter.ai/api"
Do not use ANTHROPIC_API_KEY for OpenRouter unless your gateway specifically accepts x-api-key.
LiteLLM example
export ANTHROPIC_AUTH_TOKEN="sk-litellm-your-virtual-key"
export ANTHROPIC_BASE_URL="https://your-litellm-server:4000"
API-key gateway or local vLLM example
export ANTHROPIC_API_KEY="your-key-here"
export ANTHROPIC_BASE_URL="https://your-vllm-server"
If you are not sure which variable to use, check the gateway docs and confirm whether it expects Authorization: Bearer or x-api-key.
Root cause 3: Malformed settings.json
If you configure Claude Code through ~/.claude/settings.json, invalid JSON prevents Claude Code from reading your enterprise config.
Invalid: trailing comma
{
"env": {
"ANTHROPIC_BASE_URL": "https://openrouter.ai/api",
"ANTHROPIC_AUTH_TOKEN": "sk-or-your-key",
}
}
Invalid: smart quotes
{
"env": {
“ANTHROPIC_BASE_URL”: “https://openrouter.ai/api”
}
}
Correct
{
"env": {
"ANTHROPIC_BASE_URL": "https://openrouter.ai/api",
"ANTHROPIC_AUTH_TOKEN": "sk-or-your-openrouter-key"
}
}
Validate the file
Use Python:
python3 -c "import json, os; json.load(open(os.path.expanduser('~/.claude/settings.json')))" && echo "Valid JSON"
Or use jq:
jq . ~/.claude/settings.json
If either command returns a parse error, fix the JSON before starting Claude Code.
Root cause 4: Fresh install has not completed onboarding
On fresh installs, Claude Code may not read settings.json until onboarding is marked complete.
Check:
cat ~/.claude.json | python3 -m json.tool 2>/dev/null | grep hasCompletedOnboarding
If hasCompletedOnboarding is missing or false, add it to ~/.claude.json:
{
"hasCompletedOnboarding": true,
"primaryApiKey": "sk-placeholder"
}
The primaryApiKey value is only a placeholder and is overridden by your configured provider. Use a value starting with sk- to pass the format check.
Then restart Claude Code.
Root cause 5: Gateway does not forward required headers
Claude Code sends several headers during validation and request execution.
Your gateway should forward:
anthropic-beta
anthropic-version
X-Claude-Code-Session-Id
If a proxy strips these headers, Claude Code may receive an unexpected response and return Invalid custom3p enterprise config.
nginx example
location /v1/ {
proxy_pass http://backend;
proxy_set_header anthropic-beta $http_anthropic_beta;
proxy_set_header anthropic-version $http_anthropic_version;
proxy_set_header X-Claude-Code-Session-Id $http_x_claude_code_session_id;
}
For LiteLLM, this should work by default in v1.82.9+.
If your gateway cannot forward the beta header, disable experimental betas:
export CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1
This can allow the core agent loop to work, but features that depend on beta headers may be unavailable.
Root cause 6: Enterprise policy conflict
If you use a Team or Enterprise Claude environment, managed settings can override local config and environment variables.
Check for managed settings:
ls ~/.claude/managed-settings.json 2>/dev/null && echo "Managed settings found"
Or run this inside Claude Code:
/status
If managed settings are active, ask your admin to:
- Allow your gateway domain.
- Add your gateway model IDs to
availableModels. - Remove or adjust custom base URL restrictions.
For managed deployments you control, managed settings are stored in platform-specific locations such as:
/Library/Application Support/ClaudeCode/managed-settings.json
on macOS.
Working configuration: Claude Code + OpenRouter + DeepSeek V4 Pro
OpenRouter exposes an Anthropic-compatible API. Use this configuration to route Claude Code through DeepSeek V4 Pro.
Create or update ~/.claude/settings.json:
{
"env": {
"ANTHROPIC_BASE_URL": "https://openrouter.ai/api",
"ANTHROPIC_AUTH_TOKEN": "sk-or-your-openrouter-key",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "deepseek/deepseek-v4-pro",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "deepseek/deepseek-v4-pro",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "deepseek/deepseek-v4-pro"
}
}
The model overrides matter because Claude Code may otherwise continue sending its default model ID, such as claude-sonnet-4-6, even though the base URL now points to OpenRouter.
OpenRouter may support Claude models too, so the request may succeed but route differently than intended unless you pin the model.
Compatibility note: OpenRouter does not fully implement every part of Anthropic’s streaming tool-call behavior. The main agent loop can work, but complex multi-tool chains may fail in edge cases. Track OpenRouter’s Claude Code integration docs for current compatibility details.
Working configuration: Claude Code + LiteLLM
LiteLLM is a common gateway choice for Claude Code because it can route model names and forward headers across providers.
LiteLLM config.yaml
model_list:
- model_name: claude-sonnet-4-6
litellm_params:
model: deepseek/deepseek-v4
api_key: "sk-your-deepseek-key"
- model_name: claude-opus-4-7
litellm_params:
model: deepseek/deepseek-v4-pro
api_key: "sk-your-deepseek-key"
Claude Code ~/.claude/settings.json
{
"env": {
"ANTHROPIC_BASE_URL": "http://localhost:4000",
"ANTHROPIC_AUTH_TOKEN": "sk-litellm-your-key"
}
}
With this setup, Claude Code can keep sending model IDs like claude-sonnet-4-6. LiteLLM maps those IDs to the provider model you configured.
Working configuration: Claude Code + local vLLM
For local inference with vLLM, start the server:
python -m vllm.entrypoints.openai.api_server \
--model deepseek-ai/DeepSeek-V3 \
--dtype auto \
--api-key local-key \
--port 8000
Then configure Claude Code:
export ANTHROPIC_BASE_URL="http://localhost:8000"
export ANTHROPIC_API_KEY="local-key"
export ANTHROPIC_DEFAULT_SONNET_MODEL="deepseek-ai/DeepSeek-V3"
Debugging checklist
If the previous fixes do not work, start Claude Code with debug logging:
claude --debug 2>&1 | head -100
Look for:
-
Sending request to:— confirms the final URL. -
Response status:— shows the gateway HTTP response. -
enterprise config error:— shows the internal validation failure.
Then reproduce the request manually:
curl -v -X POST "${ANTHROPIC_BASE_URL}/v1/messages" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${ANTHROPIC_AUTH_TOKEN}" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: max-tokens-3-5-sonnet-2024-07-15" \
-d '{
"model": "claude-sonnet-4-6",
"max_tokens": 10,
"messages": [{"role": "user", "content": "hi"}]
}'
Common results:
| Status | Likely issue |
|---|---|
200 |
Gateway works; compare with Claude Code debug logs |
401 |
Wrong token or wrong auth header |
403 |
Gateway policy or provider permission issue |
404 |
Wrong base URL, often trailing /v1
|
422 |
Request schema or model mapping problem |
Testing the gateway with Apidog
When debugging third-party provider integrations, Apidog helps you inspect the exact requests and responses going through your LLM gateway.
Create a collection for your gateway’s /v1/messages endpoint and save request templates for common Claude Code calls.
Use collection-level variables for:
ANTHROPIC_BASE_URL
ANTHROPIC_AUTH_TOKEN
anthropic-version
anthropic-beta
That lets you switch providers or gateway configs without editing every request.
This is useful for header-forwarding issues. You can confirm whether your gateway receives and forwards anthropic-beta, anthropic-version, and X-Claude-Code-Session-Id before spending time debugging Claude Code itself.
Related Claude Code configurations
Disable beta header dependency
If your gateway cannot forward custom beta headers:
export CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1
The core agent loop can still work, but beta-gated features may be unavailable.
Enable gateway model discovery
As of Claude Code v2.1.129, you can ask Claude Code to query your gateway’s model list:
export CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1
Claude Code queries:
/v1/models
Only model IDs starting with claude or anthropic are added to the picker. For non-Claude model IDs like DeepSeek, set a default model manually:
export ANTHROPIC_DEFAULT_SONNET_MODEL="deepseek/deepseek-v4-pro"
Add a custom model picker entry
export ANTHROPIC_CUSTOM_MODEL_OPTION="deepseek/deepseek-v4-pro"
export ANTHROPIC_CUSTOM_MODEL_OPTION_NAME="DeepSeek V4 Pro"
export ANTHROPIC_CUSTOM_MODEL_OPTION_DESCRIPTION="17x cheaper than Claude Opus"
This adds a custom entry to Claude Code’s /model picker.
Related guides
If you are configuring Claude Code with custom model backends, these guides cover related workflows:
- How to Write AGENTS.md Files for API Development Teams — configure Claude Code behavior for your stack.
- Ruflo: Multi-Agent Orchestration for Claude Code — add swarms, persistent memory, and MCP tools to Claude Code.
- Get Free Unlimited Claude API via Puter.js — browser-based alternative for client apps.
- Best Local LLMs 2026 — run inference locally through vLLM.
FAQ
Is using a third-party provider with Claude Code against Anthropic’s terms?
No. Anthropic documents and supports routing through Bedrock, Vertex AI, Foundry, and custom gateways with ANTHROPIC_BASE_URL.
What Anthropic blocked in April 2026 was third-party tools spoofing the Claude Code client ID to access Anthropic’s API through subscription pricing. Using your own gateway or provider API key is different.
Does Claude Code’s agent loop work with DeepSeek V4 Pro?
The core loop can work, including file editing, shell commands, and multi-step tasks.
The main limitations through third-party providers are MCP server tools and image/vision input. If your workflow depends on those, use the Anthropic API, Bedrock, or Vertex AI.
Why does the error say enterprise config if I am not on an enterprise plan?
Claude Code uses the enterprise config label internally for third-party provider configuration. It is not necessarily tied to your subscription tier.
Can I switch between Anthropic and a third-party provider mid-session?
Not within the same session. Claude Code reads the base URL at startup.
To switch providers:
- Exit Claude Code.
- Change your environment variables or
settings.json. - Start a new session.
DeepClaude wraps this with backend flags such as:
--backend ds
--backend anthropic
Does Claude Code support corporate proxies?
Yes. Set HTTPS_PROXY before launching Claude Code:
export HTTPS_PROXY="http://your-proxy:8080"
export ANTHROPIC_BASE_URL="https://your-internal-gateway"
For TLS interception, add the corporate CA certificate:
export NODE_EXTRA_CA_CERTS="/path/to/corporate-ca-bundle.pem"
My curl test works, but Claude Code still fails. What is different?
Claude Code may send an additional validation request that your curl command does not reproduce.
Run:
claude --debug
Compare the debug request with your curl test. Common differences include:
anthropic-betaX-Claude-Code-Session-Id- Exact model name
- Request body format
- Auth header type
Conclusion
Invalid custom3p enterprise config is usually fixable.
Start here:
- Remove
/v1fromANTHROPIC_BASE_URL. - Use the correct auth variable.
- Validate
~/.claude/settings.json. - Mark onboarding complete on fresh installs.
- Confirm your gateway forwards required headers.
- Check for managed policy overrides.
Once the config validates, Claude Code can run its agent loop through your chosen backend, including OpenRouter, LiteLLM, or local vLLM. The main tradeoffs are compatibility gaps around MCP tools, vision input, and some provider-specific streaming/tool-call behavior.

Top comments (0)