이 둘은 별칭이 아닙니다. 하나는 `x-api-key`가 되고 다른 하나는 `Authorization: Bearer`가 됩니다. 둘 다 설정되어 있으면 사용하려던 변수가 아닌 쪽이 선택될 수 있습니다. 사용자 지정 base URL에서 「키는 올바른데 인증에 실패한다」는 보고의 대부분이 이 문제입니다.
오류
# Sent as: x-api-key: <value>
export ANTHROPIC_API_KEY="sk-ant-..."
# Sent as: Authorization: Bearer <value>
export ANTHROPIC_AUTH_TOKEN="sk-kn-..."
# Where those headers go:
export ANTHROPIC_BASE_URL="https://api.kunavo.com"원인과 해결 방법 한눈에 보기
| 원인 | 해결 방법 |
|---|---|
| 게이트웨이는 bearer token을 요구하는데 API key 변수를 설정한 경우 | 대부분의 OpenAI 호환 게이트웨이는 `Authorization: Bearer`로 인증합니다. 게이트웨이 키를 ANTHROPIC_AUTH_TOKEN에 넣으세요. |
| 서로 다른 제공업체의 두 변수를 모두 설정한 경우 | 셸 프로필에 남아 있는 오래된 ANTHROPIC_API_KEY가 token과 함께 전송될 수 있습니다. 사용하지 않는 변수는 해제하세요. |
| Base URL은 설정했지만 자격 증명은 바꾸지 않은 경우 | 새 호스트를 가리킨다고 해서 이전 제공업체의 키가 그곳에서 유효해지는 것은 아닙니다. 호스트가 바뀌면 자격 증명도 함께 바꿔야 합니다. |
| 도구를 실행하는 셸과 다른 셸에 변수를 설정한 경우 | 대화형 셸에서 export한 값은 GUI로 실행된 프로세스에 전달되지 않습니다. 동일한 환경 내부에서 확인하세요. |
환경에 실제로 저장된 값을 확인하기
무엇이든 변경하기 전에 도구를 실행하는 셸에서 두 변수 모두 확인하세요. 이러한 세션 중 상당수에는 두 변수가 모두 설정되어 있습니다. 대개 아무도 기억하지 못하는 몇 달 전 프로필 수정에서 남은 값입니다.
for v in ANTHROPIC_API_KEY ANTHROPIC_AUTH_TOKEN ANTHROPIC_BASE_URL; do
printf '%-22s %s\n' "$v" "$(printenv "$v" | cut -c1-12)"
done
# Prefixes tell you the provider at a glance:
# sk-ant- Anthropic direct
# sk-kn- Kunavo호스트에 맞는 쌍을 설정하고 다른 변수는 해제하기
호스트와 자격 증명을 하나의 단위로 취급하세요. 서드파티 base URL을 사용할 때는 일반적으로 bearer token과 base URL을 함께 설정하고, 직접 API key는 명시적으로 해제하여 선택되지 않게 해야 합니다.
unset ANTHROPIC_API_KEY
export ANTHROPIC_AUTH_TOKEN="sk-kn-..."
export ANTHROPIC_BASE_URL="https://api.kunavo.com"
# On Kunavo, pin served models too: Claude Code's default and its opus and
# sonnet aliases follow Anthropic's newest models, and the sonnet alias asks
# for Sonnet 5.5, which Kunavo does not serve — unpinned, that request 404s.
export ANTHROPIC_MODEL="claude-sonnet-5"
export ANTHROPIC_DEFAULT_OPUS_MODEL="claude-opus-5-5"
export ANTHROPIC_DEFAULT_SONNET_MODEL="claude-sonnet-5"
export ANTHROPIC_DEFAULT_HAIKU_MODEL="claude-haiku-4-5"
claude머릿속이 아니라 실제 전송 내용을 확인하기
인증이 계속 실패한다면 환경 변수를 의심하지 말고, 실제로 전송된다고 생각하는 헤더를 사용해 직접 요청을 보내세요. 여기서는 200이 반환되는데 도구에서는 실패한다면 도구가 설정한 변수를 읽지 않는 것입니다. 가장 흔한 원인은 다른 셸을 사용하거나 설정 파일이 값을 덮어쓰는 경우입니다.
curl -s -o /dev/null -w '%{http_code}\n' \
"$ANTHROPIC_BASE_URL/v1/models" \
-H "Authorization: Bearer $ANTHROPIC_AUTH_TOKEN"Kunavo를 통해 호출하는 경우
Kunavo는 `Authorization: Bearer` 또는 `x-api-key`에서 키를 읽으므로 헤더가 결정 요인은 아닙니다. Claude Code에서 작동하는 조합은 여전히 ANTHROPIC_AUTH_TOKEN과 ANTHROPIC_BASE_URL입니다. token은 ANTHROPIC_API_KEY에 필요한 일회성 승인 없이 적용되며, ANTHROPIC_API_KEY는 남겨 두지 말고 해제해야 합니다. 오래된 값이 설정되어 있어 구성된 것처럼 보이지만 계속 거부되는 세션의 가장 흔한 원인이기 때문입니다. 동일한 `sk-kn-` 키는 /v1/chat/completions에 대해 OpenAI 스타일 bearer token으로 그대로 작동하므로 하나의 자격 증명으로 두 형식을 모두 사용할 수 있습니다. 사용할 모델명까지 포함한 전체 설정은 Claude Code 401 가이드.
자주 묻는 질문
둘 다 설정되어 있으면 어느 쪽이 우선하나요?
그 답에 의존하지 마세요 — 버전마다 변경되었고 SDK마다 다른 우선순위 규칙입니다. 하나만 설정하고 다른 하나는 해제하세요. 이것만이 어디서나 동일하게 작동하는 구성입니다.
ANTHROPIC_AUTH_TOKEN을 Anthropic에 직접 사용할 수 있나요?
Anthropic 자체 API는 x-api-key로 인증하므로 직접 Anthropic 키는 ANTHROPIC_API_KEY에 넣어야 합니다. token 변수는 bearer 자격 증명을 요구하는 호스트를 위한 것입니다.
SDK도 같은 변수를 사용하나요?
Python 및 TypeScript SDK는 ANTHROPIC_API_KEY를 읽고 x-api-key를 전송합니다. SDK를 bearer 인증 게이트웨이에 연결한다면 환경 변수에 의존하지 말고 자격 증명을 명시적으로 전달하세요.
관련 가이드
- 사용자 지정 base URL에서 Claude Code “API Error: 401 authentication_error” — 모든 원인
- Claude API 401 authentication_error / invalid x-api-key — 모든 원인
- OpenAI 호환 API가 401/403을 반환함 — base_url과 헤더의 함정
- “조직에서 Claude Code의 Claude 구독 액세스를 비활성화했습니다” — 세 가지 원인과 해결 방법
오류 의미에 대한 자세한 내용은 오류 참조에서 확인할 수 있습니다. 가입 및 인증 가이드를 통해 1분이면 키를 받을 수 있습니다.