SSD Nodes Learn Hosting plans →
Руководства Matt ConnorАвтор: Matt Connor

Claude Code ошибка invalid API key: как исправить

Claude Code выдает ошибку invalid API key даже при активной подписке? Узнайте, как найти переменную ANTHROPIC_API_KEY в системе и почему команда login не решает проблему.

Почему Claude Code показывает ошибку недействительного API key

Claude Code завершается с ошибкой Invalid API key по двум разным причинам, и исправления в этих случаях противоположны. Возможно, вы хотели пройти аутентификацию с помощью API key, но этот ключ неверен, отозван или принадлежит другой учётной записи. Либо вы вообще не собирались использовать ключ, но в окружении сервера осталась переменная ANTHROPIC_API_KEY, которая имеет приоритет над подпиской, с которой вы вошли. В документации Anthropic по состоянию на October 2026 это указано прямо: после подтверждения ключа, заданного в окружении, он используется вместо подписки Claude Pro, Max, Team или Enterprise даже при выполненном входе, а при claude -p ключ всегда используется, если он задан.

Сначала определите, какой из этих вариантов относится к вам, и только потом что-либо изменяйте. Запустите Claude Code и выполните /status. В документации описана строка Login method, в которой отображается учётная запись подписки, а также строка API key, которая появляется при использовании API key. Если на сервере, где вы запускали только /login, отображается строка API key, проверьте окружение, настройки и apiKeyHelper. Повторная аутентификация не удалит эти учётные данные.

Все команды ниже нужно выполнять на собственном сервере. Прежде чем продолжить, прочитайте их вывод.

Порядок выбора учетных данных и почему /login не помогает

Если доступны несколько наборов учетных данных, Claude Code выбирает их в документированном порядке:

  • Учетные данные облачного провайдера, если задана переменная CLAUDE_CODE_USE_BEDROCK, CLAUDE_CODE_USE_VERTEX или CLAUDE_CODE_USE_FOUNDRY.
  • Переменная ANTHROPIC_AUTH_TOKEN, передаваемая в заголовке Authorization: Bearer.
  • Переменная ANTHROPIC_API_KEY, передаваемая в заголовке X-Api-Key.
  • Результат выполнения скрипта apiKeyHelper.
  • Переменная CLAUDE_CODE_OAUTH_TOKEN, содержащая токен из claude setup-token.
  • Профили Anthropic, явно выбранные через ANTHROPIC_PROFILE, учетные данные федерации, выбранные через переменные окружения, а также активные или профили по умолчанию с аутентификацией oidc_federation.
  • Учетные данные OAuth подписки, которые записывает /login.
  • Активный профиль Anthropic или профиль по умолчанию с аутентификацией user_oauth, если только ANTHROPIC_PROFILE явно не выбирает его.

Читайте этот список снизу вверх. /login записывает учетные данные OAuth подписки. В Linux они сохраняются в ~/.claude/.credentials.json с правами доступа 0600. Они имеют приоритет над активным профилем user_oauth или профилем по умолчанию, если только ANTHROPIC_PROFILE явно не выбирает его, но уступают учетным данным из переменных окружения и apiKeyHelper. Одобренный API key из переменной окружения по-прежнему имеет приоритет над входом через подписку. Поэтому новый вход обновляет учетные данные, к которым сессия не обращается: вход выполнен, но это ничего не изменило. Именно поэтому очевидное исправление не помогает. С помощью CLAUDE_CODE_OAUTH_TOKEN команда /login переключает текущую сессию на новый вход. Однако новые сессии снова читают эту переменную, пока вы ее не удалите. Сессия Claude apps gateway с выполненным входом не участвует в этом порядке. Она использует токен gateway вместо этих учетных данных, даже если задана переменная облачного провайдера.

Интерактивные сессии добавляют еще один шаг, который часто вводит пользователей в заблуждение. В документации указано, что при обнаружении API key в окружении программа один раз предлагает подтвердить или отклонить его использование и сохраняет этот выбор. Если вы подтвердили использование несколько месяцев назад, это разрешение по-прежнему действует, и ключ сохраняет приоритет над входом через подписку. Если вы отклонили ключ, он игнорируется без повторного запроса. Возникает противоположная проблема: переменная задана, env показывает ее, но сессия ее не использует. Изменить выбор можно с помощью переключателя "Use custom API key" в /config. Этот переключатель отображается только при наличии ANTHROPIC_API_KEY в окружении. В неинтерактивном режиме, то есть при использовании claude -p в скрипте или задании cron, запрос не выводится: при наличии ключ всегда используется.

Как найти лишний ANTHROPIC_API_KEY на VPS?

Сначала убедитесь, что он существует в shell, из которого вы запускаете Claude Code.

env | grep -i anthropic

Затем выполните исправление, приведённое на собственной странице Anthropic по устранению неполадок. Одновременно оно служит проверкой:

unset ANTHROPIC_API_KEY
claude

Если Claude Code запускается и /status теперь показывает вашу подписку, причина подтверждена. Переменная появится в следующем shell, если startup-файл по-прежнему задаёт её, поскольку unset изменяет только shell, в котором вы выполнили команду. В остальной части этого раздела описано, как найти источник этой переменной.

Профили shell и общесистемные файлы окружения

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. На сервере расширьте поиск. Модуль pam_env читает /etc/environment, если он включён в конфигурации PAM (pluggable authentication modules) для входа в систему. Поэтому ключ, заданный на уровне системы, оказывается в вашей сессии. Файлы в /etc/profile.d/ выполняются, когда профиль login shell подключает их. Сервис systemd автоматически не читает .bashrc. Проверьте, запускает ли его команда shell явно или подключает профиль. Важный файл зависит от способа запуска Claude Code.

Юниты systemd

Юнит не читает профиль shell. Его окружение включает строки Environment= и EnvironmentFile= в самом юните и во всех drop-in-файлах, а также переменные, переданные менеджером сервисов.

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

systemctl cat выводит файл юнита, а затем его drop-in-файлы, включая переопределения в /etc/systemd/system/claude-agent.service.d/. systemctl show -p Environment показывает назначения Environment= в юните. Также проверьте все файлы EnvironmentFile=, поскольку их содержимое отдельно считывается при запуске процесса. Для сервиса, работающего от имени вашего пользователя, добавьте --user к обеим командам. После изменения юнита выполните sudo systemctl daemon-reload и перезапустите сервис. Окружение формируется при запуске процесса, а уже работающий процесс сохраняет полученную копию.

Сессии tmux и screen, пережившие изменение конфигурации

Эта причина может отнять несколько часов. Сервер tmux сохраняет окружение, с которым был запущен, а новые панели наследуют объединённые глобальное окружение и окружение сессии. Вы удаляете export из .bashrc, открываете новую панель, но старый ключ всё ещё присутствует.

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

set-environment -r помечает имя для удаления из окружения, которое tmux передаёт новым процессам, а добавление -g выполняет то же самое для глобального окружения сервера. Уже открытые панели сохраняют собственную копию, поскольку окружение процесса можно изменить только изнутри этого процесса. После удаления export отсоединитесь, выполните tmux kill-server и запустите новую сессию. Это важно знать перед настройкой долгой сессии Claude Code в tmux на VPS, поскольку такая сессия как раз может пережить три последовательных изменения конфигурации.

Чтобы прочитать окружение уже работающего процесса, запросите его у ядра:

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

Команда выводит значения, переданные процессу во время exec. Позднейшие изменения, например значения, загруженные Claude Code из настроек, в выводе не отражаются. Для чтения этого файла вы должны быть владельцем процесса или root. pgrep -n claude выбирает самое новое совпадение, поэтому при наличии нескольких процессов проверьте PID.

Docker и Compose

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

Первая команда показывает окружение внутри работающего контейнера, включая данные из --env-file, блока environment: или строки ENV, встроенной в image. docker compose config выводит compose-файл с подставленными переменными. Так вы видите значение, которое будет передано, а не записанный вами заполнитель ${ANTHROPIC_API_KEY}. Обе команды выводят секреты в терминал, поэтому выполняйте их в сессии, которую можно очистить. По умолчанию Compose также загружает файл .env из каталога проекта для интерполяции. Значение из этого файла попадает в контейнер, если конфигурация Compose передаёт его дальше.

Файл настроек, который сохраняется после всех исправлений в shell

Файлы настроек Claude Code содержат блок env. В документации прямо описан конфликт: если одна и та же переменная задана и в shell, и в блоке env файла настроек, то в большинстве сессий применяется значение из файла настроек. Исключение составляют сессии, запущенные приложением Claude Desktop или self-hosted environment runner. В них приоритет имеет окружение запуска. Для claude, запущенного в терминале на сервере, ключ, записанный в этом файле, имеет приоритет над любым unset, который вы зададите.

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

Проверьте файлы проекта и пользовательский файл. .claude/settings.json обычно добавляют в систему контроля версий, поэтому он доступен всем, кто клонирует репозиторий. Организации также могут передавать управляемые настройки, которые имеют приоритет над вашими файлами. Если вы нашли ключ, который не можете удалить, обратитесь к ответственному за эти настройки.

Другая ветка: ключ действительно неверен

Если /status показывает API key, и это ожидаемо, воспринимайте ошибку буквально. В справочнике ошибок Anthropic указано, что Invalid API key · Fix external API key означает: API отклонил ключ, полученный из ANTHROPIC_API_KEY или скрипта apiKeyHelper, либо Claude Code заблокировал ключ до отправки. Для этой ошибки проверьте следующее:

  • Проверьте ключ на опечатки.
  • Убедитесь в Console, что ключ не был отозван.
  • Убедитесь, что такой инструмент, как direnv, dotenv-плагин для shell или терминал IDE, не загрузил устаревший ключ из файла проекта .env.

Проверьте значение, не выводя его в историю терминала:

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

Если длина на один или два символа больше ожидаемой, обычно это означает, что при копировании вместе со значением попал перевод строки или кавычка, либо файл ключа был сохранён с окончаниями строк Windows и сохранил символ возврата каретки. Чтение файла с помощью $(cat keyfile) не сохраняет обычный завершающий перевод строки, поскольку Bash удаляет завершающие переводы строк из результата подстановки команды. Но он не удаляет возврат каретки перед этим переводом строки, поэтому файл с окончаниями строк Windows всё равно добавляет в переменную один лишний символ. Текущие версии обнаруживают символы, которые заголовок не может содержать, до отправки: когда сообщение продолжается после Fix external API key и содержит описание вроде Invalid X-Api-Key header value from ANTHROPIC_API_KEY: it contains a line break, Claude Code остановил запрос, и API не получил ключ. Изогнутая кавычка обнаруживается той же проверкой, но обычная кавычка является допустимым символом заголовка. Поэтому она отправляется как часть заголовка X-Api-Key, и переданные учётные данные не совпадают с созданным вами ключом.

Проверьте ANTHROPIC_AUTH_TOKEN в том же выводе, поскольку этот параметр находится выше API key в порядке следования. Оставшийся bearer token после эксперимента с proxy означает, что ключ, который вы сейчас исправляете, вообще не является отправляемыми учётными данными. Также стоит проверить ANTHROPIC_BASE_URL в этом выводе: старое значение указывает клиенту на gateway, которого может уже не существовать. Общую картину на уровне заголовков и назначение каждого из этих параметров описывает материал как работает аутентификация Anthropic API по API key. Прежде чем решать, какие учётные данные вообще должны храниться на этой машине, ознакомьтесь с материалом сравнение входа по подписке и API key.

Эта ошибка не связана с нехваткой ресурсов. Если запросы завершаются ошибкой 529 Overloaded, вы столкнулись с ошибкой перегруженной модели, и менять учётные данные не требуется.

Почему мой скрипт apiKeyHelper завершается с ошибкой?

apiKeyHelper — ключ настройки, задающий скрипт, который Claude Code запускает для получения учётных данных. Он нужен для ротации или краткоживущих токенов, например для ключа, полученного из vault. Контракт прост: вывести текущий ключ в стандартный вывод и завершиться успешно. В документации указано, что скрипт, который завершается с ошибкой, превышает время ожидания или ничего не выводит, приводит к сбою запросов с Your apiKeyHelper script is failing в течение трёх попыток.

Запустите его вручную и проверьте обе части этого контракта:

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

Ненулевой код завершения означает ошибку, даже если ключ выведен правильно. Вспомогательный скрипт, который выводит Fetching credential... в стандартный вывод перед ключом, также не соответствует требованиям: начиная с v2.1.227 Claude Code отклоняет вывод, содержащий что-либо кроме ключа, и сообщает, что вспомогательный скрипт returned output that cannot be used as an API key. В старых версиях эта строка передавалась вместе с учётными данными. Выводите сообщения о ходе выполнения в стандартный поток ошибок. Внутри сеанса /status показывает строку apiKeyHelper со значениями Failing, содержащими последний код завершения и вывод ошибки.

Затем протестируйте его так, как его будет запускать сервис:

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

env -i запускает скрипт с почти пустым окружением. Вспомогательный скрипт, который вызывает aws, vault или gcloud из каталога, добавленного вашим .bashrc в PATH, работает при ручной проверке и завершается с ошибкой в сервисе, если среда запуска этого сервиса не содержит такой каталог. Убедитесь, что скрипт исполняемый, а всё, что он вызывает, использует абсолютный путь, либо задайте PATH непосредственно в скрипте.

На сервере важны ещё два документированных поведения. По умолчанию Claude Code повторно запускает вспомогательный скрипт через пять минут, а CLAUDE_CODE_API_KEY_HELPER_TTL_MS задаёт другой интервал. Поэтому конфигурация, которая работает при запуске и перестаёт работать через час, завершается с ошибкой при обновлении, а не при запуске. Если вспомогательному скрипту требуется более десяти секунд для возврата ключа, Claude Code показывает в строке приглашения предупреждение с указанием прошедшего времени. Это предупреждение означает медленный вызов, а не неисправность. Оно заранее сообщает о проблеме до того, как превышение времени ожидания приведёт к ошибке.

Действительно ли вам нужен API key на этом сервере?

Решение не всегда заключается в удалении. Оставьте ключ, если у машины есть основания для отдельной тарификации:

  • Автономный агент на VPS, оплачиваемый через Console, не расходует лимиты подписки пользователя.
  • Неинтерактивные запуски, где claude -p не имеет терминала для подтверждения действий, и ключ используется всегда при его наличии.
  • Машины, к которым не привязана подписка.
  • Общая или клиентская машина, на которой не следует хранить данные для входа в личную подписку.

Обычно всё решает стоимость, и сравнение цен на API и подписку поможет вам определиться.

Удалите ключ, если это ваша машина и вы уже платите за подписку. Затем закрепите это удаление. Вместо экспорта ключа в ~/.bashrc, откуда его наследует каждая интерактивная оболочка, передайте его только тому сервису, которому он нужен:

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

Установите для этого файла права 600, владельцем должен быть пользователь, от имени которого работает сервис. Ваши интерактивные сессии не увидят его, поэтому ваш собственный claude продолжит использовать подписку, а сервис — ключ. Если вам нужны учетные данные подписки там, где нет браузера, claude setup-token выведет OAuth-токен, который можно вставить в CLAUDE_CODE_OAUTH_TOKEN. Стоит ознакомиться с документированными ограничениями этого метода, прежде чем полагаться на него: он позволяет выполнять только запросы к моделям, поэтому сессии Remote Control и коннекторы к claude.ai через него недоступны. Однократное принятие решения для каждой машины и запись его в unit-файл предотвращают сбои, о которых идет речь на этой странице, поскольку они часто возникают из-за ключа, о настройке которого никто не помнит. Ограничение доступа для этих учетных данных — отдельная задача, описанная в безопасном запуске Claude Code на VPS.

Предостережение перед использованием радикальных мер. /logout удаляет сохраненные учетные данные, и в документации указано, что это также очищает сохраненные логины серверов MCP (model context protocol) и секреты плагинов, поэтому будьте готовы повторно авторизовать их после этого.

FAQ

Почему Claude Code сообщает об ошибке недействительного API key, если у меня есть подписка?

Причина в том, что ANTHROPIC_API_KEY в окружении имеет приоритет над входом через подписку после его подтверждения. В документации Anthropic указано, что подтверждённый key, заданный в окружении, используется вместо подписки Pro, Max, Team или Enterprise, даже если вы вошли в систему. В неинтерактивном режиме с -p этот key всегда используется, если он задан. Выполните /status в Claude Code, чтобы узнать, какие учётные данные выбрала сессия. Если появляется строка API key, а вы не задавали её намеренно, выполните unset ANTHROPIC_API_KEY и снова запустите claude, чтобы подтвердить причину.

Исправляет ли запуск /login ошибку недействительного API key?

Нет, пока подтверждённый API key из окружения продолжает использоваться. /login записывает OAuth-учётные данные подписки ниже учётных данных из окружения и apiKeyHelper, но выше активного или default-профиля user_oauth, если только ANTHROPIC_PROFILE явно не выбирает его. Вход выполняется успешно, но затем эти учётные данные не используются. Поэтому повторный вход ничего не меняет. Удалите переменную из места, где она задана, или отключите переключатель "Use custom API key" в /config. Согласно документации, этот переключатель отображается только когда ANTHROPIC_API_KEY задана в окружении.

Как узнать, какой метод аутентификации использует Claude Code?

Выполните /status в сессии. В документации описана строка Login method, которая показывает учётную запись подписки, и строка API key, появляющаяся при использовании API key. Сравните результат с env | grep -i anthropic в той же оболочке, из которой вы запускали Claude Code. Если Claude Code запускается сервисом или контейнером, проверьте окружение запуска с помощью tr '\0' '\n' < /proc/<pid>/environ. Этот файл показывает значения, переданные во время exec, поэтому также проверьте файлы настроек на наличие значений, которые Claude Code загружает позже.

Скрипт apiKeyHelper работает при ручном запуске. Почему Claude Code всё равно завершается с ошибкой?

Обычно причина связана с окружением или кодом завершения. Claude Code запускает helper в собственном окружении процесса. Поэтому сервис, в котором отсутствует запись PATH из вашей терминальной сессии, не может найти команду, работающую при ручной проверке. Проверьте скрипт с помощью env -i HOME="$HOME" PATH=/usr/bin:/bin /path/to/helper, а затем проверьте echo $?. Документированная ошибка возникает, если скрипт завершается с ошибкой, превышает время ожидания, ничего не выводит или выводит что-либо кроме key. Она отображается как Your apiKeyHelper script is failing. Начиная с v2.1.227, баннер или строка журнала в standard output приводит к немедленной ошибке helper, поэтому сообщения о ходе выполнения нужно отправлять в standard error.

Была ли эта статья полезной?