Claude Code apiKeyHelper script is failing: Causes and 5 Tested Fixes
apiKeyHelper script is failing in Claude Code means your helper returned no usable key. Run it by hand, print only the key, exit 0. Tested on 2.1.318.

Claude Code shows apiKeyHelper script is failing when the command in your apiKeyHelper setting doesn’t hand back a usable key. Without a key the request goes out with an empty credential and the API answers 401. Run the helper command yourself, fix whatever it complains about (usually an expired vault or SSO session), and make sure it prints only the key to stdout and exits with code 0. We reproduced the error on Claude Code 2.1.318 on November 5, 2026; the output is below. Causes and fixes follow the official Claude Code error reference.
The full message reads:
Your apiKeyHelper script is failing · This usually means you need to re-authenticate with your provider · Run /status to see the script's error output
What apiKeyHelper script is failing means
apiKeyHelper is a setting that names a shell command. Claude Code runs it (through /bin/sh on macOS and Linux, cmd on Windows) and sends what it prints as both the X-Api-Key and Authorization: Bearer headers. The error appears when one of three things happened:
- the command exited with an error or timed out;
- the command printed nothing to stdout;
- the command printed something besides the key, such as a login banner or a log line. Claude Code then reports
returned output that cannot be used as an API keyand says what is wrong without repeating the output. Before v2.1.227 it sent whatever was printed after trimming whitespace.
Claude Code re-runs the script and retries up to two more times, so the message appears within three attempts. Before v2.1.208 it burned the whole retry budget and showed a generic 401. If you are not sure which settings file holds the helper, our guide to settings.json locations lists every path and which one wins.
Our test: a failing helper on Claude Code 2.1.318
We pointed an isolated Claude Code 2.1.318 at a local mock API and used a helper that prints an error to stderr and exits 1. This is what came back:
$ claude -p "say ok" # helper script exits 1
Your apiKeyHelper script is failing · This usually means you need to re-authenticate with your provider · Run /status to see the script's error output
# stderr (printed 3 times)
apiKeyHelper failed: exited 1: vault: session expired, run vault login
# what our mock API received (3 requests)
POST /v1/messages Authorization: "Bearer" x-api-key: "" -> 401
Three things stand out. The message on stdout matches the docs word for word. The reason is on stderr, prefixed with apiKeyHelper failed:, and it is only shown there in -p mode; in an interactive session you read it in /status or in the Authentication panel. And the failed requests carried an empty Authorization: Bearer header, which is the behaviour described in GitHub issue #100514 (still open at the time of writing).
A second helper that printed one log line before the key failed like this:
# helper prints "Fetching key from relay..." and then the key
apiKeyHelper failed: returned output that cannot be used as an API key: it contains a line break at character 27 (41 characters on 2 lines). The script must print only the key to stdout.
How to fix apiKeyHelper script is failing
- Run the helper yourself. Copy the command from
apiKeyHelperand run it in the same shell. Check the exit code and look for stray output: - Re-authenticate with your provider if the command reports an expired session: sign in to your SSO, run
vault login, or refresh whatever the script reads from. - Print only the key. The output must be a single token of printable ASCII, up to 16,384 characters, followed by exit code 0. Send logs and banners to stderr with
>&2. - Check
/status. From v2.1.274 theapiKeyHelperrow showsFailingwith the exit code and the script’s error output, and disappears after the next successful run. - Start a new session after the fix and send a short prompt to confirm.
~/bin/get-gateway-key.sh; echo "exit=$?"
~/bin/get-gateway-key.sh 2>/dev/null | od -c | tail -3
The second line shows the raw bytes stdout carries. A \n in the middle of the output or any text before the key means the helper will fail. Trailing newlines are fine: in our 2.1.318 test, a key followed by a blank line or by Windows \r\n still worked. A working helper, based on the gateway guide:
#!/bin/sh
# send every log line to stderr; stdout carries only the key
echo "fetching key..." >&2
vault kv get -field=api_key secret/llm-gateway/claude-code
{
"apiKeyHelper": "~/bin/get-gateway-key.sh"
}
On Windows, call PowerShell explicitly and escape the backslashes in JSON:
{
"apiKeyHelper": "powershell -NoProfile -File C:\\scripts\\get-gateway-key.ps1"
}
If the helper is defined in a project’s .claude/settings.json or settings.local.json, an interactive session doesn’t run it until you accept the workspace trust prompt.
Why /login doesn’t help
The helper’s output outranks a saved claude.ai login for as long as the setting exists, so /login changes nothing. To go back to subscription login, remove apiKeyHelper from every settings file that sets it. The authentication precedence is: cloud provider credentials, ANTHROPIC_AUTH_TOKEN, ANTHROPIC_API_KEY, apiKeyHelper, CLAUDE_CODE_OAUTH_TOKEN, Anthropic profile, then /login. Login errors that do respond to /login are covered in our 401 OAuth token has expired fix.
apiKeyHelper script is failing behind a gateway or relay
Check this section if the error started after you pointed ANTHROPIC_BASE_URL at a gateway or a third-party endpoint, for example to run Claude Code with DeepSeek or another provider. If your key is a fixed string, you don’t need a helper. Set it as ANTHROPIC_AUTH_TOKEN (Bearer) or ANTHROPIC_API_KEY (x-api-key) and remove apiKeyHelper:
{
"env": {
"ANTHROPIC_BASE_URL": "https://your-relay.example.com",
"ANTHROPIC_AUTH_TOKEN": "sk-your-relay-key"
}
}
In our test with ANTHROPIC_AUTH_TOKEN set and a broken helper still configured, the request succeeded with the token, but stderr still printed apiKeyHelper failed: once. Remove the leftover helper to get rid of that noise. If your gateway is LiteLLM, issue #100514 reports that the empty Bearer header from a failed helper comes back as 401 with Malformed API Key passed in, which points you at the gateway when the fault is in the helper.
FAQ
How often does Claude Code run the helper?
It caches the output for five minutes, adjustable with CLAUDE_CODE_API_KEY_HELPER_TTL_MS in milliseconds. It also re-runs the helper after a 401 or 403, and from v2.1.246 before a request when the cached value is an expired JWT. Those two extra cases apply only when ANTHROPIC_AUTH_TOKEN isn’t set (settings reference).
My helper is slow. Is that the problem?
Possibly. A command that times out counts as a failure. Since v2.1.77 Claude Code shows a notice when the helper takes longer than 10 seconds. The docs don’t state the exact timeout, so we can’t give you a number.
Where can I find other Claude Code errors?
Our Claude Code errors hub collects them. A related message, Could not resolve authentication method, means no credential reached the API client at all.
Sources: Claude Code errors reference, apiKeyHelper settings reference, LLM gateway guide, GitHub issue #100514, Claude Code changelog (2.1.77, 2.1.208, 2.1.227, 2.1.274). Checked November 5, 2026 against Claude Code 2.1.318.