SSD Nodes Learn Hosting plans →
가이드 Matt Connor작성자 Matt Connor · 업데이트됨 2026-09-15

Claude Code invalid API key 오류 해결 방법

Claude Code에서 유효하지 않은 API 키 오류가 발생하는 원인을 분석합니다. 환경 변수 ANTHROPIC_API_KEY가 로그인 정보보다 우선순위가 높아 발생하는 문제이며, 이를 제거하여 구독 계정을 정상적으로 인식시키는 방법을 설명합니다.

Claude Code에서 잘못된 API 키 오류가 발생하는 이유

Claude Code가 Invalid API key 오류와 함께 실패하는 원인은 두 가지이며, 해결 방법은 서로 정반대입니다. API 키로 인증하려 했으나 해당 키가 잘못되었거나, 취소되었거나, 다른 계정의 키일 수 있습니다. 혹은 애초에 키를 사용할 의도가 없었음에도 서버 환경 변수에 남아 있는 ANTHROPIC_API_KEY 값이 로그인한 구독 정보보다 우선순위를 갖는 경우입니다. 2026년 9월 기준 Anthropic 문서에 따르면, 두 번째 사례의 경우 사용자가 로그인한 상태라도 Claude Pro, Max, Team 또는 Enterprise 구독 대신 환경 변수에 설정된 키가 우선적으로 사용됩니다.

무언가를 변경하기 전에 현재 어떤 상태인지 확인해야 합니다. Claude Code를 시작하고 /status를 실행하십시오. 문서에 따르면 Login method 행에는 구독 계정이 표시되며, API 키가 사용 중일 때는 API key 행이 나타납니다. /login만 실행했던 환경에서 API 키 행이 보인다면 환경 변수가 문제이며, 재인증을 수행해도 이 문제는 해결되지 않습니다.

아래의 모든 내용은 사용자의 서버에서 직접 실행할 명령어입니다. 명령을 실행하기 전에 출력 결과를 먼저 확인하십시오.

자격 증명 우선순위와 /login이 도움이 되지 않는 이유

여러 자격 증명이 존재할 때 Claude Code는 문서화된 순서에 따라 하나를 선택합니다.

  • CLAUDE_CODE_USE_BEDROCK, CLAUDE_CODE_USE_VERTEX 또는 CLAUDE_CODE_USE_FOUNDRY이 설정된 경우 클라우드 공급자 자격 증명.
  • Authorization: Bearer 헤더로 전송되는 ANTHROPIC_AUTH_TOKEN 변수.
  • X-Api-Key 헤더로 전송되는 ANTHROPIC_API_KEY 변수.
  • apiKeyHelper 스크립트의 출력.
  • claude setup-token에서 가져온 토큰을 담고 있는 CLAUDE_CODE_OAUTH_TOKEN 변수.
  • Anthropic 프로필 및 페더레이션 자격 증명.
  • /login이 기록하는 구독 OAuth 자격 증명.

이 목록을 아래에서부터 읽어 보십시오. /login는 자격 증명을 가장 마지막 순위에 기록하며, Linux 환경에서는 파일 모드 0600으로 ~/.claude/.credentials.json에 저장됩니다. 그 위에 있는 모든 환경 자격 증명이 우선합니다. 따라서 새로 로그인을 수행해도 세션이 참조하지 않는 자격 증명만 갱신될 뿐입니다. 로그인은 성공했지만 실제로는 사용되지 않은 것입니다. 이것이 바로 명백한 해결책이 아무런 효과가 없는 이유입니다.

대화형 세션에는 사용자를 혼란스럽게 하는 단계가 하나 더 있습니다. 문서에 따르면 환경에서 발견된 API 키를 승인하거나 거부하라는 메시지가 한 번 표시되며, 선택한 내용은 기억됩니다. 몇 달 전에 클릭하여 승인한 내용이 여전히 유효합니다. /config의 "Use custom API key" 토글을 통해 이를 변경할 수 있는데, 이 토글은 환경에 ANTHROPIC_API_KEY가 설정되어 있을 때만 나타납니다. 스크립트나 cron 작업 내부와 같이 claude -p이 설정된 비대화형 모드에서는 메시지가 전혀 표시되지 않으며, 키가 존재하면 항상 해당 키가 사용됩니다.

VPS에서 잘못 설정된 ANTHROPIC_API_KEY를 찾는 방법

먼저 Claude Code를 실행하는 셸에 해당 키가 존재하는지 확인합니다.

env | grep -i anthropic

그다음 Anthropic의 문제 해결 페이지에서 제공하는 수정 명령을 실행합니다. 이 명령은 테스트 역할도 겸합니다.

unset ANTHROPIC_API_KEY
claude

Claude Code가 시작되고 /status가 현재 구독 정보를 올바르게 표시한다면 원인을 찾은 것입니다. unset는 명령을 입력한 셸만 변경하므로, 다음 셸에서는 변수가 다시 나타납니다. 이 섹션의 나머지 부분은 해당 변수를 설정하는 주체를 찾는 방법을 다룹니다.

셸 프로필 및 시스템 전체 환경 설정 파일

grep -rn ANTHROPIC ~/.bashrc ~/.bash_profile ~/.profile ~/.zshrc \
  ~/.config/fish/config.fish /etc/environment /etc/profile /etc/profile.d/ 2>/dev/null

Anthropic 페이지에서는 ~/.zshrc, ~/.bashrc, ~/.profile을 언급합니다. 서버 환경에서는 검색 범위를 넓혀야 합니다. /etc/environment는 로그인 시 모든 사용자에 대해 PAM(pluggable authentication modules)이 읽어 들이며, 동료가 설정한 키가 본인의 세션에 포함되는 주된 원인입니다. /etc/profile.d/에 있는 파일들은 로그인 셸에서 실행됩니다. .bashrc은 대화형 셸에서만 읽히므로, systemd 서비스 내부의 오류를 설명할 수 없다는 점에 유의하십시오. 어떤 파일이 문제인지는 Claude Code가 어떻게 시작되었는지에 따라 달라집니다.

systemd 유닛

유닛은 사용자의 셸 프로필을 읽지 않습니다. 유닛과 드롭인 파일의 Environment=EnvironmentFile= 라인에서 환경 변수를 가져옵니다.

systemctl cat claude-agent.service
systemctl show -p Environment claude-agent.service

systemctl cat는 유닛 파일과 /etc/systemd/system/claude-agent.service.d/의 모든 드롭인 파일을 출력합니다. 보통 설정 재정의(override)는 이곳에 숨어 있습니다. systemctl show -p Environment은 systemd가 실제로 프로세스에 전달할 내용을 출력합니다. 본인 계정으로 실행 중인 서비스라면 두 명령 모두에 --user을 추가하십시오. 유닛을 수정한 후에는 sudo systemctl daemon-reload을 실행하고 서비스를 재시작해야 합니다. 환경 변수는 프로세스 시작 시점에 구성되며, 실행 중인 프로세스는 전달받은 복사본을 유지하기 때문입니다.

편집 후에도 남아 있는 tmux 및 screen 세션

이 문제는 많은 시간을 낭비하게 만듭니다. tmux 서버는 시작될 때의 환경을 유지하며, 새로운 창(pane)은 현재 셸이 아닌 서버의 환경을 상속받습니다. .bashrc에서 export를 제거하고 새 창을 열어도 이전 키가 그대로 남아 있는 이유입니다.

tmux show-environment | grep -i ANTHROPIC
tmux set-environment -r ANTHROPIC_API_KEY

set-environment -r은 tmux가 새 프로세스에 전달하는 환경에서 해당 이름을 제거하며, -g을 추가하면 서버의 전역 환경에서도 동일하게 적용됩니다. 이미 열려 있는 창은 각자의 복사본을 유지합니다. 프로세스의 환경은 해당 프로세스 내부에서만 변경할 수 있기 때문입니다. export를 제거한 후 가장 확실한 방법은 세션을 분리(detach)하고, tmux kill-server를 실행한 뒤 새 세션을 시작하는 것입니다. screen도 동일하게 동작합니다. VPS에서 tmux로 Claude Code 세션을 장시간 실행하기 전에 알아두어야 할 사항입니다. 해당 세션은 설정 변경을 여러 번 반복해도 계속 살아남는 프로세스이기 때문입니다.

이미 실행 중인 프로세스의 환경을 읽으려면 커널에 직접 요청하십시오.

tr '\0' '\n' < /proc/$(pgrep -n claude)/environ | grep -i anthropic

이 명령은 프로세스가 실행(exec)될 때 전달받은 값을 출력하며, 이는 실제로 사용 중인 값입니다. 이 파일을 읽으려면 프로세스 소유자이거나 root 권한이 있어야 합니다. pgrep -n claude는 가장 최근에 일치하는 항목을 선택하므로, 여러 프로세스가 실행 중이라면 PID를 확인하십시오.

Docker 및 Compose

docker exec claude-agent env | grep -i anthropic
docker compose config

첫 번째 명령은 실행 중인 컨테이너 내부의 환경 변수를 보여줍니다. 여기에는 --env-file, environment: 블록, 또는 이미지에 포함된 ENV 라인의 내용이 모두 포함됩니다. docker compose config은 변수가 해석된 compose 파일을 출력하므로, 작성한 ${ANTHROPIC_API_KEY} 플레이스홀더 대신 실제로 전달될 값을 볼 수 있습니다. 두 명령 모두 터미널에 보안 정보를 출력하므로, 내용을 지울 수 있는 세션에서 실행하십시오. Compose는 별도의 지시가 없어도 compose 파일 옆에 있는 .env 파일을 자동으로 로드하며, 이것이 아무도 추가한 기억이 없는 키의 흔한 원인입니다.

모든 셸 수정 사항보다 우선하는 설정 파일

Claude Code 설정 파일은 env 블록을 포함하며, 문서에서는 이 충돌에 대해 명시하고 있습니다. 셸과 설정 파일의 env 블록에 동일한 변수가 설정되어 있으면 설정 파일의 값이 우선합니다. 그곳에 작성된 키는 사용자가 입력하는 모든 unset보다 강력합니다.

grep -rn ANTHROPIC ~/.claude/settings.json .claude/settings.json .claude/settings.local.json 2>/dev/null

사용자 파일뿐만 아니라 프로젝트 파일도 확인하십시오. .claude/settings.json는 일반적으로 커밋되므로 저장소를 복제하는 모든 사람과 공유됩니다. 조직 차원에서 관리형 설정을 배포할 수도 있으며, 이는 본인의 파일보다 우선합니다. 삭제할 수 없는 키를 발견했다면 해당 관리자에게 문의해야 합니다.

다른 분기: 키가 정말로 잘못된 경우

/status 명령으로 API 키를 확인했는데 의도한 결과가 맞다면, 오류 메시지를 그대로 받아들여야 합니다. Anthropic의 오류 참조 문서에서는 Invalid API key 오류의 원인을 다음과 같이 설명합니다.

  • 키 형식이 잘못되었거나 틀렸습니다.
  • 키가 취소되었거나 만료되었습니다.
  • 키가 다른 조직이나 계정에 속해 있습니다.

터미널 기록에 출력되지 않도록 주의하며 값을 검사하십시오.

echo "len=${#ANTHROPIC_API_KEY} tail=${ANTHROPIC_API_KEY: -6}"

예상보다 길이가 1~2자 더 길다면 복사 및 붙여넣기 과정에서 개행 문자가 포함되었거나, $(cat keyfile) 명령으로 파일 끝의 개행 문자까지 함께 읽혔을 가능성이 큽니다. 이 값은 X-Api-Key 헤더로 전송되므로, 불필요한 문자가 섞이면 생성한 키와 다른 인증 정보가 전달됩니다.

동일한 출력에서 ANTHROPIC_AUTH_TOKEN 항목도 확인하십시오. API 키보다 상단에 위치하기 때문입니다. 프록시 테스트 후 남은 bearer 토큰이 있다면, 현재 수정 중인 키가 아닌 다른 인증 정보가 전송되고 있을 수 있습니다. 해당 출력에서 ANTHROPIC_BASE_URL 항목도 읽어볼 가치가 있습니다. 이전 값이 설정되어 있으면 클라이언트가 더 이상 존재하지 않는 게이트웨이를 가리킬 수 있기 때문입니다. 헤더 수준의 상세 내용은 Anthropic API 키 인증 작동 방식에서 각 항목이 무엇을 의미하는지 확인할 수 있습니다. 이 장비에 어떤 인증 정보를 저장할지 결정하기 전에 구독 로그인과 API 키의 차이를 먼저 읽어보시기 바랍니다.

이 오류가 절대 아닌 경우도 있습니다. 바로 용량 문제입니다. 세션 인증은 성공했으나 작업 도중 요청이 실패한다면, 이는 모델 과부하 오류를 보고 있는 것이며 인증 정보를 변경할 필요가 없습니다.

apiKeyHelper 스크립트가 실패하는 이유는 무엇입니까?

apiKeyHelper은 Claude Code가 자격 증명을 얻기 위해 실행하는 스크립트를 지정하는 설정 키입니다. 이는 볼트(vault)에서 가져온 키와 같이 순환되거나 수명이 짧은 토큰을 위해 존재합니다. 이 계약은 간단합니다. 현재 키를 표준 출력으로 인쇄하고 성공적으로 종료하면 됩니다. 문서에 따르면 오류와 함께 종료되거나, 시간 초과가 발생하거나, 아무것도 출력하지 않는 스크립트는 3번의 시도 내에 Your apiKeyHelper script is failing 오류와 함께 요청을 실패하게 만듭니다.

수동으로 실행하여 해당 계약의 두 가지 조건을 모두 확인하십시오.

out=$(/usr/local/bin/anthropic-key.sh)
echo "exit=$? len=${#out} tail=${out: -6}"

키가 올바르게 출력되더라도 0이 아닌 종료 코드는 실패를 의미합니다. 키 앞에 Fetching credential...을 표준 출력으로 인쇄하는 도우미 스크립트 역시 실패로 간주되는데, 해당 줄이 자격 증명의 일부가 되기 때문입니다. 진행 상황 메시지는 표준 오류(standard error)로 보내십시오.

그런 다음 서비스가 실행할 방식대로 테스트하십시오.

env -i HOME="$HOME" PATH=/usr/bin:/bin /usr/local/bin/anthropic-key.sh
echo "exit=$?"

env -i는 거의 비어 있는 환경에서 스크립트를 시작합니다. .bashrcPATH에 추가한 디렉터리에서 aws, vault 또는 gcloud을 호출하는 도우미 스크립트는 테스트할 때는 작동하지만 실제 환경에서는 실패합니다. 실행 중인 Claude Code 프로세스가 사용자의 .bashrc을 읽지 않기 때문입니다. 스크립트가 실행 가능한지 확인하고, 호출하는 모든 항목에 절대 경로를 사용하거나 스크립트 내부에서 PATH을 설정하십시오.

서버 환경에서는 문서화된 두 가지 동작이 더 중요합니다. Claude Code는 기본적으로 5분 후에 도우미 스크립트를 다시 실행하며, CLAUDE_CODE_API_KEY_HELPER_TTL_MS는 다른 간격을 설정합니다. 따라서 시작 시에는 작동하다가 한 시간 후에 중단되는 설정은 실행 시점이 아니라 갱신 시점에 실패하는 것입니다. 도우미 스크립트가 키를 반환하는 데 10초 이상 걸리면 Claude Code는 프롬프트 바에 경과 시간과 함께 경고 알림을 표시합니다. 이 알림은 스크립트가 고장 난 것이 아니라 호출이 느리다는 것을 의미하며, 시간 초과로 오류가 발생하기 전에 미리 확인할 수 있는 경고입니다.

이 서버에 API 키가 정말로 필요한가?

해결책이 항상 삭제인 것은 아닙니다. 다음과 같은 경우에는 키를 유지해야 합니다:

  • Console에 청구되는 VPS의 무인 에이전트는 개인 구독 한도를 소모하지 않습니다.
  • claude -p이 승인을 위한 터미널을 갖지 못하고 키가 존재할 때 항상 사용되는 비대화형 실행 환경인 경우.
  • 구독이 연결되지 않은 머신.
  • 개인 구독 로그인 정보를 저장해서는 안 되는 공유 머신이나 클라이언트 머신.

비용이 보통 이 결정을 좌우하며, API 및 구독 요금 비교에서 이를 계산할 수 있습니다.

본인 소유의 머신이고 이미 구독료를 지불하고 있다면 키를 삭제하십시오. 그 후 삭제 상태를 유지하십시오. 모든 대화형 셸이 상속받는 ~/.bashrc에 키를 export하는 대신, 키가 필요한 서비스에만 제공하십시오:

[Service]
EnvironmentFile=/etc/claude-agent.env

이 파일의 권한은 600으로 설정하고, 서비스를 실행하는 사용자가 소유하도록 하십시오. 대화형 세션은 이 파일을 보지 않으므로, 본인의 claude는 계속 구독 정보를 사용하고 서비스는 키를 사용하게 됩니다. 브라우저가 없는 환경에서 구독 자격 증명이 필요하다면, claude setup-token을 실행하여 CLAUDE_CODE_OAUTH_TOKEN에 붙여넣을 OAuth 토큰을 출력하십시오. 이 토큰을 사용하기 전에 문서화된 제한 사항을 알아두는 것이 좋습니다. 이 토큰은 모델 요청만 수행할 수 있으므로, Remote Control 세션이나 claude.ai 커넥터는 사용할 수 없습니다. 머신당 한 번 이 결정을 내리고 unit 파일에 기록하는 것이 이 페이지에서 다루는 오류를 방지하는 방법입니다. 아무도 설정한 기억이 없는 키로 인해 문제가 시작되기 때문입니다. 자격 증명을 배치한 후 접근 범위를 제한하는 것은 별도의 작업이며, VPS에서 안전하게 Claude Code 실행하기에서 다룹니다.

강력한 조치를 취하기 전 주의 사항이 하나 있습니다. /logout은 저장된 자격 증명을 삭제합니다. 문서에 따르면 이 명령은 저장된 MCP(Model Context Protocol) 서버 로그인 정보와 플러그인 비밀 정보도 함께 삭제하므로, 이후 다시 인증해야 할 수 있음을 유의하십시오.

FAQ

구독료를 지불했는데도 Claude Code에서 유효하지 않은 API 키라고 나오는 이유는 무엇입니까?

환경 변수에 설정된 ANTHROPIC_API_KEY가 구독 로그인 정보보다 우선하기 때문입니다. Anthropic 문서에 따르면, 로그인 상태라 하더라도 환경 변수에 키가 설정되어 있으면 Pro, Max, Team 또는 Enterprise 구독 정보 대신 해당 키가 사용됩니다. 또한 -p을 사용한 비대화형 모드에서는 키가 존재하면 항상 우선적으로 사용됩니다. Claude Code 내에서 /status을 실행하여 세션이 어떤 자격 증명을 선택했는지 확인하십시오. 의도적으로 설정한 적이 없는데도 API key 항목이 나타난다면, unset ANTHROPIC_API_KEY을 실행한 뒤 claude를 다시 시작하여 원인을 확인하십시오.

/login을 실행하면 유효하지 않은 API 키 오류가 해결됩니까?

해당 변수가 설정되어 있는 동안에는 해결되지 않습니다. /login는 구독 OAuth 자격 증명을 기록하는데, 이는 환경 변수나 apiKeyHelper보다 낮은 우선순위를 가집니다. 로그인은 성공하지만 실제로는 무시되기 때문에 반복해서 실행해도 아무런 변화가 없습니다. 변수가 설정된 곳에서 해당 변수를 제거하거나, /config에서 "Use custom API key" 토글을 끄십시오. 문서에 따르면 이 토글은 환경에 ANTHROPIC_API_KEY이 설정되어 있을 때만 나타납니다.

Claude Code가 어떤 인증 방식을 사용하는지 어떻게 확인합니까?

세션에서 /status를 실행하십시오. 문서에 따르면 구독 계정을 보여주는 Login method 항목과 API 키가 사용 중일 때 나타나는 API key 항목이 있습니다. 이를 Claude Code를 실행한 셸에서 env | grep -i anthropic와 비교해 보십시오. 서비스나 컨테이너에서 Claude Code를 실행 중이라면 tr '\0' '\n' < /proc/<pid>/environ을 사용하여 프로세스 환경을 읽어야 합니다. 실행 중인 프로세스는 현재 셸의 환경 변수가 아니라, 시작될 당시에 부여받은 환경 변수를 유지하기 때문입니다.

apiKeyHelper 스크립트는 직접 실행하면 잘 작동하는데, 왜 Claude Code에서는 실패합니까?

대개 환경 변수나 종료 상태 코드 때문입니다. Claude Code는 자체 프로세스에서 헬퍼를 실행하는데, 이 프로세스는 사용자의 셸 프로필을 읽지 않습니다. 따라서 .bashrcPATH 항목에 의존하는 헬퍼는 터미널에서는 작동해도 Claude Code 내부에서는 실패합니다. env -i HOME="$HOME" PATH=/usr/bin:/bin /path/to/helper으로 테스트한 뒤 echo $?을 확인하십시오. 문서화된 실패 사례는 스크립트가 오류와 함께 종료되거나, 시간 초과가 발생하거나, 아무것도 출력하지 않는 경우를 포함하며, 이는 Your apiKeyHelper script is failing로 나타납니다. 표준 출력으로 키 이외의 내용이 출력되면 해당 내용이 자격 증명의 일부로 포함되므로, 진행 상황 메시지는 표준 오류로 출력하십시오.