사후 분석: 오래된 OAuth와 격리된 크론 작업으로 인한 Claude Max + OpenClaw 청구 오류

✍️ OpenClawRadar📅 게시일: May 12, 2026🔗 Source
사후 분석: 오래된 OAuth와 격리된 크론 작업으로 인한 Claude Max + OpenClaw 청구 오류
Ad

자체 호스팅 OpenClaw 설정과 Claude Max가 할당량을 초과하지 않았음에도 billing error — API key has run out of credits를 반환하기 시작했습니다. 이틀간의 디버깅 끝에 두 가지 근본 원인과 고장을 무작위로 보이게 하는 킬 체인이 밝혀졌습니다.

근본 원인 1: 오래된 OAuth 토큰이 전체 제공자를 오염시킴

auth-profiles.json에 두 개의 항목이 있었습니다: 유효한 anthropic:claude-cli OAuth 프로필과 sk-ant-oat01-... 토큰이 있는 anthropic:manual 프로필입니다. 수동 토큰이 만료되었을 때, OpenClaw는 해당 프로필만 실패 처리하지 않고 제공자 수준의 결제 실패로 분류하여 전체 anthropic 제공자를 블랙리스트에 등록하여, 정상 OAuth 프로필을 포함한 모든 모델을 건너뛰었습니다. 로그에는 다음이 표시되었습니다:

reason: "billing" errorPreview: "Provider anthropic has billing issue (skipping all models)" chain_exhausted

유효한 갱신 토큰이 있는 정상 OAuth 프로필은 시도조차 되지 않았습니다.

수정: auth-profiles.jsonopenclaw.json에서 anthropic:manual을 완전히 제거합니다. anthropic:claude-cli만 유지합니다.

근본 원인 2: 격리된 cron 작업이 별도의 결제 버킷에 도달함

OpenClaw에는 두 가지 실행 경로가 있습니다:

  • 메인 세션/usr/bin/claude 바이너리를 실행하며 Max/Pro 구독으로 청구됨 ✅
  • 격리/내장 실행 — Anthropic API에 직접 HTTP 요청을 보내며 Extra Usage 버킷으로 청구됨 ❌

sessionTarget: isolated로 설정된 cron 작업은 독립형 내장 에이전트를 실행하며, 이는 CLI가 보내는 Claude Code 헤더 없이 Anthropic API에 직접 HTTP로 호출합니다. Anthropic은 이를 Extra Usage 버킷으로 라우팅하며, 이는 완전히 별도의 할당량입니다. Extra Usage가 꺼져 있으면 모든 격리된 cron 실행은 400을 반환합니다. OpenClaw는 상황을 악화시킵니다: 하나의 결제 오류가 auth-state.jsondisabledUntil을 약 24시간 앞으로 설정하여, 모든 요청(일반 채팅 포함)을 쿨다운이 발생할 때까지 잠급니다. 잠금은 게이트웨이 재시작 후에도 유지됩니다.

Ad

전체 킬 체인

  1. 게이트웨이 재시작 → 놓친 cron 작업이 따라잡기 위해 대기열에 추가됨
  2. 격리 에이전트가 내장 실행자로 실행 → Anthropic API에 직접 HTTP 호출(CLI 헤더 없음)
  3. Extra Usage 버킷 → 400 오류
  4. OpenClaw가 인증 프로필을 약 24시간 동안 잠금 → 모든 요청(일반 채팅 포함) 차단

수정 사항

  1. 결제 잠금 즉시 해제:
    python3 -c "
    import json
    with open('/home/USER/.openclaw/agents/main/agent/auth-state.json') as f:
        d = json.load(f)
    if 'usageStats' in d:
        for profile in d['usageStats']:
            d['usageStats'][profile].pop('disabledUntil', None)
            d['usageStats'][profile].pop('failureCounts', None)
            d['usageStats'][profile].pop('errorCount', None)
            d['usageStats'][profile].pop('disabledReason', None)
            d['usageStats'][profile].pop('lastFailureAt', None)
    with open('/home/USER/.openclaw/agents/main/agent/auth-state.json', 'w') as f:
        json.dump(d, f, indent=2)
    print('해제 완료.')
    "
    openclaw gateway restart
  2. 모든 cron 작업을 isolated에서 main으로 이동:
    python3 -c "
    import json
    with open('/home/USER/.openclaw/cron/jobs.json') as f:
        d = json.load(f)
    jobs = d if isinstance(d, list) else d.get('jobs', [])
    for j in jobs:
        if j.get('sessionTarget') == 'isolated':
            print(f'수정 중: {j["name"]}')
            j['sessionTarget'] = 'main'
    with open('/home/USER/.openclaw/cron/jobs.json', 'w') as f:
        json.dump(d, f, indent=2)
    print('완료.')
    "

대상: 할당량을 초과하지 않았음에도 무작위 결제 오류가 발생하는 Claude Max 또는 Pro로 OpenClaw를 자체 호스팅하는 모든 사용자.

📖 전체 출처 읽기: r/openclaw

Ad

👀 See Also