如何使用 ANTHROPIC_BASE_URL 修正「Auth conflict」、401 和 /v1/v1 404 錯誤
How do you fix "Auth conflict", 401, and /v1/v1 404 with ANTHROPIC_BASE_URL?
排查 ANTHROPIC_BASE_URL 的「Auth conflict」、401 和 /v1/v1 404 錯誤時,應確認用戶端沒有重複加入 /v1,並只保留一個有效的 API 金鑰來源。先以直接 curl 請求核對最終 URL 和驗證來源,再使用相同環境啟動命令列用戶端。
How do you fix "Auth conflict", 401, and /v1/v1 404 with ANTHROPIC_BASE_URL?
401 Unauthorized usually means the client sent the wrong credential or sent two conflicting credential sources. The /v1/v1 error is a URL composition problem: the documented base URL already ends in /v1, so a client that appends another /v1 creates an invalid path. Set the base URL once, use one API key source, and test the final request URL before running the full coding workflow.
TL;DR
Use this base URL when the client accepts a base URL that already includes the API version:
export ANTHROPIC_BASE_URL="https://api.xisu.ai/v1"
Do not configure an additional /v1 suffix in the client. The valid chat endpoint is:
POST $ANTHROPIC_BASE_URL/chat/completions
For authentication, keep one active API key source. Remove stale shell variables, inherited credentials, or an interactive login token that the client may prefer over the configured key. Then verify the request with a direct curl call before debugging the client itself.
Environment
This test uses a command-line coding client configured with a custom API base URL and an API key. The provider endpoint is an API-compatible chat interface. The documented base URL is the value exported in the TL;DR above, referred to below as $ANTHROPIC_BASE_URL.
The documented model used in the minimal request below is:
gpt-6-luna
The supported chat endpoint is:
POST /v1/chat/completions
The test date for this article is 2026-10-27. Documentation facts were checked against the source material updated on 2026-10-25; the API compatibility reference is marked updated on 2026-10-04. The test method is deliberately split into two stages:
- Test the URL and key with a direct HTTP request.
- Start the CLI client with the same environment and confirm that it does not modify the path or select a second credential.
The exact client version is not specified here, so this article does not assume a particular version-specific flag or configuration file format.
Error log
These are representative failure patterns. The important values are the status code, the final request path, and the credential source selected by the client.
Error 1: authentication conflict
Auth conflict: more than one authentication source is configured.
Some clients can read credentials from an interactive session, a local configuration file, and environment variables. If more than one source is active, the client may reject the request before sending it or may select a credential different from the one expected by the user.
Error 2: 401 response
HTTP/1.1 401 Unauthorized
{
"error": {
"message": "authentication failed"
}
}
A 401 response means the server received the request but did not accept its authentication. Typical causes are an empty key, a stale key, an extra quote in the variable value, or a client that sent a different key than the one being inspected in the shell.
Error 3: duplicated API version
HTTP/1.1 404 Not Found
GET /v1/v1/chat/completions
The configured base URL already ends in /v1. If the client adds /v1/chat/completions to a base URL that it first normalizes incorrectly, the final path becomes /v1/v1/chat/completions. The server cannot match that route.
Cause
1. The base URL is being treated as both a root and a versioned path
A base URL is not always handled consistently. One client expects a bare host root, then adds /v1. Another client expects the complete versioned base URL ($ANTHROPIC_BASE_URL) and adds only the operation path.
Therefore, the client configuration must not add another /v1 segment. The correct composition is:
base URL: $ANTHROPIC_BASE_URL
path: /chat/completions
result: $ANTHROPIC_BASE_URL/chat/completions
The incorrect composition is:
base URL: $ANTHROPIC_BASE_URL
path: /v1/chat/completions
result: $ANTHROPIC_BASE_URL/v1/chat/completions
2. More than one credential source is active
An authentication conflict is usually local configuration state, not a model or endpoint problem. Check for these sources:
- An API key variable in the current shell.
- A key exported by the parent shell or terminal profile.
- A local client configuration file.
- An interactive login session.
- A wrapper script that injects another authorization header.
The safest test is to start a clean shell, export one key, and print only non-secret metadata such as whether the variable is present and its character count. Do not print the key itself.
3. The key is valid but the request is not the request you inspected
A successful environment check does not prove that the client used that value. Debug output may reveal that the client selected a stored token or rewrote the base URL. Compare the final URL and the selected authentication source, not only the values in your shell.
Fix (code)
Step 1: create a clean test shell
Start a new shell process without relying on inherited aliases or wrapper scripts. Then define the base URL exactly once.
export ANTHROPIC_BASE_URL="$ANTHROPIC_BASE_URL"
export API_KEY="replace-with-your-api-key"
Use the actual API key in your local environment. Do not include it in source control, shell history shared with other users, issue reports, or logs.
Step 2: verify the variable shape without exposing the secret
python - <<'PY'
import os
base = os.environ.get("ANTHROPIC_BASE_URL", "")
key = os.environ.get("API_KEY", "")
print("base_url:", base)
print("base_url_ends_with_v1:", base.endswith("/v1"))
print("key_present:", bool(key))
print("key_length:", len(key))
PY
Expected output should show the exact base URL, True for the version suffix, and a nonzero key length. The key value itself must not appear.
Step 3: test the documented chat endpoint directly
curl --fail-with-body \
--request POST \
--url "$ANTHROPIC_BASE_URL/chat/completions" \
--header "Authorization: Bearer ${API_KEY}" \
--header "Content-Type: application/json" \
--data '{
"model": "gpt-6-luna",
"messages": [
{"role": "user", "content": "Return the word OK."}
]
}'
This test separates transport and authentication from client-specific URL handling. If it succeeds, the key and documented route work independently of the CLI client. If it returns 401, fix the key source before changing the base URL. If it returns 404 for /v1/chat/completions, check the exact URL in the command and remove any wrapper that rewrites it.
Step 4: remove duplicate path configuration
Keep the base URL as:
$ANTHROPIC_BASE_URL
Then configure the client so its request path is only the operation path, not another versioned path. In pseudoconfiguration:
base_url = $ANTHROPIC_BASE_URL
path_prefix = empty
operation = /chat/completions
Do not combine these values:
base_url = $ANTHROPIC_BASE_URL
path_prefix = /v1
operation = /chat/completions
If the client cannot disable its hard-coded /v1 suffix, its URL builder is incompatible with this base URL format. Use a client configuration mode that accepts the complete versioned base URL, or call the documented endpoint through a small wrapper that constructs the URL exactly once. Do not guess a different undocumented base URL.
Step 5: reduce authentication to one source
Before starting the client, remove temporary variables that may override the intended key. For example:
unset OLD_API_KEY
unset SESSION_TOKEN
export ANTHROPIC_BASE_URL="$ANTHROPIC_BASE_URL"
export API_KEY="replace-with-your-api-key"
The variable names used by a specific client may differ. The rule is unchanged: one key, one authorization header, and one active login source. If the client has an interactive login mode, sign out of that mode for the test or use a clean profile. Do not troubleshoot a mixed credential state.
Error table
| Symptom | Likely cause | Verification | Fix |
|---|---|---|---|
Auth conflict before a request is sent |
Environment credentials and stored login are both active | Start a clean shell and inspect which credential sources are enabled | Keep one API key source and disable the other source |
401 Unauthorized |
Empty, stale, malformed, or unexpected API key | Run the direct curl request and compare the selected key source |
Replace the key and remove overrides; do not print the key |
404 with /v1/v1/chat/completions
|
The client appended /v1 to an already versioned base URL |
Enable safe request logging and inspect the final path | Configure $ANTHROPIC_BASE_URL as the complete base and remove the extra suffix |
400 model_not_supported_for_endpoint |
A model was sent to the wrong endpoint | Check whether the request uses chat or embeddings | Use chat models with /v1/chat/completions and vector models with /v1/embeddings
|
| The direct request works but the CLI fails | The CLI rewrites the URL or chooses another credential | Compare the direct request with client debug output | Fix client URL composition or start the client with a clean profile |
Testing environment and references
The procedure above is based on the documented quick-start flow and the API compatibility reference. The quick-start reference specifies the versioned base URL shown in the TL;DR, while the compatibility reference specifies POST /v1/chat/completions and explains that request parameters are passed through without automatic rewriting.
- Quick-start API setup (the same documentation also covers API compatibility and endpoints)
The direct curl test is intentionally minimal: one URL, one key, one model, and one chat message. Add streaming, tools, retries, or custom headers only after this request succeeds. Otherwise, multiple changes can hide the original failure.
FAQ
Does changing the model fix a 401?
No. A 401 is an authentication failure. First verify the key source and the authorization header with the direct request. Change the model only when the server reports a model or endpoint compatibility error.
Should /v1 appear twice when using a versioned base URL?
No. With $ANTHROPIC_BASE_URL as the base URL, the final chat request should be $ANTHROPIC_BASE_URL/chat/completions. A final path containing /v1/v1 indicates duplicate URL composition.
What is the safest way to debug an authentication conflict?
Use a clean shell, configure one key, avoid interactive login state, and print only non-secret metadata. Then run the direct curl request before launching the full client. This identifies whether the problem is the credential, the endpoint, or the client’s configuration layer.
The author works on the Xisu AI team.
來源:DEV Community · dev.to