문제 해결

오류 대조표: Claude Code와 Codex로 중계 API를 쓸 때 흔한 오류

같은 오류 문구라도 공식 서비스에 직결할 때와 중계를 거칠 때 원인이 완전히 다른 경우가 많습니다. 이 대조표는 「네트워크 → 인증 → 프로토콜 → 모델 → context」 다섯 계층으로 구성하고, 계층마다 복사해 쓸 수 있는 탐색 명령과 판단 기준을 제공합니다.

검증일 2026-10-26적용 대상
Claude Code 2.xCodex CLI 0.154.0

이 표를 사용하는 방법

오류 원문에서 답을 찾으려 서두르지 말고, 먼저 어느 계층의 문제인지 정하세요. AI 클라이언트의 오류는 거의 이 다섯 계층에서 나옵니다:

  1. 네트워크 계층: 요청이 서버에 도달하지 못함
  2. 인증 계층: 도달했지만 key가 인정되지 않음
  3. 프로토콜 계층: key는 인정되었지만 경로/형식이 틀림
  4. 모델 계층: 프로토콜은 통과했지만 모델이 존재하지 않음
  5. context 계층: 모델은 돌고 있지만 입력이 너무 김

계층으로 나누는 가치는 이렇습니다: 계층마다 해결 방법이 완전히 다르고, 오류 원문만 봐서는 어느 계층인지 알기 어렵습니다.

HTTP 상태별 원인 확인

다음 명령은 모델 목록과 세 가지 프로토콜을 확인하고 각 요청의 HTTP 상태를 표시합니다:

curl을 실행할 같은 터미널에서 자리표시자를 자신의 KimiSeek API Key로 바꿔 설정하세요. 클라이언트에 저장한 인증 정보는 이 셸 환경 변수에 자동으로 설정되지 않습니다:

Shell · API key
# Replace the placeholder with your own key from the dashboard.
export KIMISEEK_API_KEY="ks-your-key"
Shell · API diagnostics
# Inspect each HTTP status and error body; a model list does not prove sufficient balance.
# 1. Is the key valid at all? (lists models)
curl -sS --max-time 30 -w '\nHTTP %{http_code} /v1/models\n' https://api.kimiseek.app/v1/models \
  -H "Authorization: Bearer ${KIMISEEK_API_KEY:?Set KIMISEEK_API_KEY before running this command}"

# 2. OpenAI Chat Completions
curl -sS --max-time 30 -w '\nHTTP %{http_code} /v1/chat/completions\n' https://api.kimiseek.app/v1/chat/completions \
  -H "Authorization: Bearer ${KIMISEEK_API_KEY:?Set KIMISEEK_API_KEY before running this command}" \
  -H "Content-Type: application/json" \
  -d '{"model":"deepseek-v4-pro-0813","messages":[{"role":"user","content":"ping"}],"max_tokens":8}'

# 3. Anthropic Messages (the protocol Claude Code speaks)
curl -sS --max-time 30 -w '\nHTTP %{http_code} /v1/messages\n' https://api.kimiseek.app/v1/messages \
  -H "x-api-key: ${KIMISEEK_API_KEY:?Set KIMISEEK_API_KEY before running this command}" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{"model":"deepseek-v4-pro-0813","max_tokens":8,"messages":[{"role":"user","content":"ping"}]}'

# 4. OpenAI Responses (the protocol Codex speaks)
curl -sS --max-time 30 -w '\nHTTP %{http_code} /v1/responses\n' https://api.kimiseek.app/v1/responses \
  -H "Authorization: Bearer ${KIMISEEK_API_KEY:?Set KIMISEEK_API_KEY before running this command}" \
  -H "Content-Type: application/json" \
  -d '{"model":"deepseek-v4-pro-0813","input":"ping","max_output_tokens":16}'

각 응답 뒤의 HTTP 상태와 본문의 error.code, error.type, message를 확인하세요. 실패한 단계만으로 프로토콜 지원 여부를 판단할 수 없습니다. 모델 목록의 200은 키가 유효하다는 뜻이며 잔액을 보장하지 않습니다. 잔액이 0이면 1단계는 200, 2단계는 402가 될 수 있습니다.

상태 또는 오류의미다음 조치
200이며 응답 구조가 정상해당 요청은 성공했지만 모든 도구 기능이 검증된 것은 아님클라이언트 설정과 실제 도구 호출 확인
401 / 403인증 정보, 키 사용 한도 또는 모델 접근 권한 문제키 활성화, 만료, 한도와 업스트림 권한 확인
402 / insufficient_balance계정 잔액 부족충전 후 재시도. 프로토콜 설정 변경 불필요
400 / 404와 model_not_found, not_found_error 또는 모델 없음 메시지잘못되거나 비활성화된 ID, 업스트림 모델 권한 부족목록의 전체 ID를 사용하고 채널 및 모델 권한 확인
400과 잘못된 매개변수 메시지요청 필드 또는 모델 제한 불일치오류 본문에 따라 메시지, 도구, token 한도 확인
404와 경로 또는 endpoint가 없다는 명시적 메시지경로 오류 또는 게이트웨이가 제공하지 않는 APIBase URL과 /v1을 확인한 뒤 프로토콜 지원 확인. 404만으로 모델과 경로 문제를 구분할 수 없음
429속도 제한, 할당량 또는 업스트림 과부하본문을 확인하고 잠시 후 재시도하거나 사용량 조정
5xx게이트웨이 또는 업스트림의 일시 장애오류와 요청 ID를 보관하고 나중에 재시도
HTTP 000 / curl 연결 또는 시간 초과 오류HTTP 응답 없음. 각 탐색 요청은 최대 30초 대기DNS, 프록시, 네트워크 확인. 시간 초과만으로 프로토콜 미지원을 판단하지 않음

Claude Code 쪽

자격 증명 없음

Claude Code · no credentials
Invalid API key · Please run /login

이 문구가 나오면 Claude Code가 자격 증명을 전혀 받지 못한 것입니다. ANTHROPIC_AUTH_TOKEN이 Claude Code를 실행한 그 shell에서 적용되는지 확인하세요. 흔한 실수는 A 터미널에서 export하고 B 터미널에서 실행하는 것입니다.

401 인증 실패

Claude Code · 401
API Error: 401 {"type":"error","error":{"type":"authentication_error","message":"invalid api key"}}

원인을 확률 순으로 정리하면:

  1. key를 복사할 때 공백이나 개행이 함께 들어감
  2. key가 이미 폐기되었거나 할당량이 소진됨
  3. ANTHROPIC_API_KEY를 썼지만 값이 비어 있어 클라이언트가 로그인 상태로 폴백

403 forbidden

Claude Code · 403
API Error: 403 {"type":"error","error":{"type":"forbidden","message":"invalid x-api-key"}}

이 문구는 직결에서 보통 key가 유효하지 않다는 뜻입니다. 중계를 거칠 때 더 흔한 원인은 요청 헤더 표기 방식입니다. 어떤 게이트웨이는 Authorization: Bearer만 받고, 어떤 곳은 x-api-key만 받습니다. KimiSeek은 둘 다 받지만, 중간에 프록시를 한 겹 더 두면 header가 재작성될 수 있습니다.

model not found

Claude Code · model not found
API Error: 400 {"type":"error","error":{"type":"invalid_request_error","message":"model: deepseek-v4-flash-0731 not found"}}

두 가지 가능성입니다: 모델명을 잘못 썼거나, 이미 종료된 모델을 썼거나. 종료된 모델 id는 「종료됨」이라고 알려 주지 않고 계속 not found를 반환합니다. 시간을 가장 많이 낭비하는 함정이 여기입니다. 설정을 한참 뒤지고 있었는데 실제로는 모델이 세대 교체된 경우입니다.

모델 페이지에서 실제 id로 교체하세요.

스트리밍 응답이 중간에 끊김

Claude Code · stream cut
API Error: stream disconnected before completion: stream closed before completion

스트리밍 연결이 도중에 끊겼습니다. 이 순서로 확인하세요:

  1. 로컬 HTTP 프록시(HTTPS_PROXY)가 가로막고 있는지
  2. 회사 네트워크에 응답 타임아웃이 있는지
  3. 서버에서 단일 요청 시간 제한이 걸렸는지

업스트림 요청 타임아웃은 Claude Code가 사용하는 /v1/messages에서 600초, Codex가 사용하는 /v1/responses에서 175초입니다. 클라이언트나 중간 프록시가 더 일찍 연결을 끊을 수 있으므로 실제 엔드포인트와 오류 내용을 확인하세요.

context 초과

Claude Code · context overflow
API Error: 400 {"type":"error","error":{"type":"invalid_request_error","message":"prompt is too long: 210000 tokens > 200000 maximum"}}

여기서 200000은 클라이언트 또는 모델의 상한이며, 여러분이 생각한 숫자가 아닐 수 있습니다. DeepSeek V4 Pro를 연결할 때 실제 상한은 1M이므로, 200000이 보인다면 요청이 목표 모델까지 가지 않았거나 클라이언트가 Claude 규격에 맞춰 스스로 잘라낸 것입니다.

Codex 쪽

401 Missing bearer

Codex · 401
■ unexpected status 401 Unauthorized: Missing bearer

config.toml의 env_key는 변수 이름일 뿐이고, 실제 값은 환경에 있어야 합니다. 이 오류는 「변수 이름은 썼지만 환경 변수가 비어 있다」는 뜻입니다.

404 Not Found

Codex · 404
■ unexpected status 404 Not Found

열에 여덟은 base_url에 /v1을 빠뜨린 경우입니다. Codex는 base_url + "/responses"를 조립하므로 /v1이 없으면 사이트 경로로 요청이 갑니다.

base_url을 확인한 뒤 응답 본문에서 모델을 찾지 못한 오류인지도 확인하세요. 게이트웨이에 /v1/responses가 정말 없다면 호환 게이트웨이나 변환 계층을 사용해야 합니다. 현재 Codex는 wire_api = "chat"을 허용하지 않습니다. Codex 가이드를 참고하세요.

스트림 중단

Codex · stream cut
■ stream disconnected before completion

Claude Code의 스트리밍 문제와 같지만, Codex는 중단에 더 민감합니다. 실행 루프가 완전한 이벤트 스트림에 의존하기 때문입니다. 네트워크가 불안정할 때는 재시도에 기대지 말고 네트워크를 바꾸세요.

네트워크 계층의 두 가지 전형

Shell · network layer
fetch failed
ECONNREFUSED 127.0.0.1:7890

fetch failed는 Node의 일반적인 네트워크 오류라 문자 그대로는 정보가 없습니다. 구체적인 원인은 ECONNREFUSED 줄을 봐야 합니다. 127.0.0.1:7890 같은 로컬 포트를 가리키면 요청이 로컬 프록시에 넘어갔는데 프록시가 꺼져 있거나 규칙이 잘못된 것입니다.

이런 문제가 「게이트웨이가 죽었다」로 가장 많이 오진됩니다. 판별법은 이렇습니다: curl은 되는데 클라이언트만 안 된다면, 기본적으로 클라이언트가 있는 shell의 환경 변수와 curl이 있는 shell의 환경 변수가 다른 것입니다.

같은 오류 문구, 직결과 중계의 원인 차이

중계를 쓸 때 가장 먼저 세워야 할 멘탈 모델입니다:

오류공식 직결중계 경유
invalid x-api-keykey 자체가 무효header 이름을 게이트웨이가 인식하지 못하거나 중간 프록시가 재작성
model not found모델명 오타게이트웨이의 모델 매핑 표에 이 id가 없거나 종료된 모델 사용
stream disconnected공식 서비스 일시 장애로컬 프록시, 회사 네트워크, 게이트웨이 타임아웃 중 하나
prompt is too long200K 초과게이트웨이가 context가 더 작은 업스트림 모델로 요청을 넘김
401key 오류key는 맞지만 환경 변수가 클라이언트 프로세스까지 전달되지 않음

문제를 제기할 때 함께 보낼 것

누군가에게 묻거나 티켓을 올린다면 아래 네 가지가 모두 있어야 합니다. 하나라도 빠지면 아무도 원인을 짚어 줄 수 없습니다:

  1. 오류 원문(잘린 스크린샷이 아니라 전체 한 줄)
  2. curl 계층 탐색 결과 — 네 단계 중 어디서 실패했는지
  3. 클라이언트 버전(claude --version / codex --version)
  4. 사용한 모델 id와 Base URL(key는 마스킹)

검증 날짜

  • 검증 날짜: 2026-10-26
  • 오류 예시는 문제 계층을 찾기 위한 것입니다. 문구는 클라이언트 버전에 따라 달라질 수 있으므로 문의할 때 설치된 버전도 알려 주세요. Codex 설정은 0.154.0으로 확인했습니다.

자주 묻는 질문

curl은 되는데 클라이언트는 왜 안 되나요?

가장 흔한 원인은 환경 변수가 같은 shell에 없는 것입니다. 클라이언트는 자기 프로세스의 환경을 읽으므로 다른 터미널에서 export해도 소용이 없습니다. 클라이언트를 실행한 shell에서 echo $ANTHROPIC_AUTH_TOKEN에 값이 있는지 먼저 확인하세요.

403과 401은 어떻게 구분하나요?

401은 「당신이 누구인지 모르겠다」, 403은 「당신이 누구인지는 알지만 이 일은 허용하지 않는다」입니다. 중계를 거칠 때 403은 header 표기나 라우팅 정책 문제가 많고, 401은 key 자체나 환경 변수 문제가 많습니다.

context 초과가 200000이라고 나오는데 모델은 1M이라고 되어 있습니다. 왜인가요?

요청이 여러분이 생각한 그 모델까지 가지 않았다는 뜻입니다. 모델 id를 잘못 써서 기본 모델로 떨어졌거나, 클라이언트가 Claude 규격에 맞춰 스스로 잘라냈을 수 있습니다. /v1/models로 id를 확인하고, 클라이언트 설정의 context window를 다시 보세요.

재시도로 스트림 중단이 해결되나요?

보통은 아닙니다. 스트림 중단은 연결 계층의 문제이고, 재시도는 같은 실패를 한 번 더 반복할 뿐입니다. 프록시와 네트워크를 먼저 확인하고, 그다음 긴 작업을 잘게 나누세요.