[BUG][Bedrock] `x-anthropic-billing-header` text injected into system prompt causes 400 on Bedrock

Status Fixed / completed
Reported on v2.1.37
Maintainer reply None cached
Activity 11 comments · opened Feb 8, 2026 · closed Feb 20, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Claude Code v2.1.37 unconditionally injects the string x-anthropic-billing-header: cc_version=...; cc_entrypoint=...; cch=00000; as a text block in the system prompt content array. When the backend is Amazon Bedrock, the API rejects this with:

400 x-anthropic-billing-header is a reserved keyword and may not be used in the system prompt.

This is distinct from the anthropic-beta HTTP header issues reported in #22893, #21625, #11672, etc. Those are about unsupported HTTP headers. This is about reserved keyword text content being placed inside the system prompt body itself.

Evidence from Binary Analysis

The billing header is assembled and placed into the system prompt unconditionally in the compiled binary:

// 1. Generated as a string:
B = `x-anthropic-billing-header: cc_version=${VERSION}.${hash}; cc_entrypoint=${entrypoint}; cch=00000;`

// 2. In the system prompt assembly function, it's identified and placed as the first text block:
if (q.startsWith("x-anthropic-billing-header")) captured = q;
// ...
if (captured) blocks.push({text: captured, cacheScope: null});

This injection is not gated by:

  • CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS
  • ENABLE_TOOL_SEARCH
  • Platform detection (bedrock/vertex/firstParty)
  • Any environment variable

Debug Log Confirmation

From ~/.claude/debug/ on two separate failing sessions:

Session 1 (variant execution via --print):

[DEBUG] Tool search disabled for model 'us.anthropic.claude-haiku-4-5-20251001-v1:0': model does not support tool_reference blocks.
[DEBUG] attribution header x-anthropic-billing-header: cc_version=2.1.37.981; cc_entrypoint=cli; cch=00000;
[DEBUG] [API:request] Creating client, ANTHROPIC_CUSTOM_HEADERS present: false, has Authorization header: false
...
[ERROR] API error (attempt 1/11): 400 400 x-anthropic-billing-header is a reserved keyword and may not be used in the system prompt.

Session 2 (separate invocation):

[DEBUG] Auto tool search disabled: 1178 tokens (threshold: 20000, 10% of context) [source: query]
[DEBUG] attribution header x-anthropic-billing-header: cc_version=2.1.37.fbe; cc_entrypoint=cli; cch=00000;
[DEBUG] [API:request] Creating client, ANTHROPIC_CUSTOM_HEADERS present: false, has Authorization header: false
...
[ERROR] API error (attempt 1/11): 400 400 x-anthropic-billing-header is a reserved keyword and may not be used in the system prompt.

Key observations:

  • ANTHROPIC_CUSTOM_HEADERS present: false — not caused by custom headers
  • Tool search was already disabled in both sessions — ENABLE_TOOL_SEARCH=0 would not help
  • The billing header hash suffix changes between calls in the same session (.981 vs .fbe)

What Should Happen?

When the backend is Bedrock, Claude Code should either:

  1. Not inject the billing header string into the system prompt text, or
  2. Send it through a mechanism that Bedrock accepts (e.g., HTTP headers or request metadata), or
  3. Provide an environment variable to suppress it

Steps to Reproduce

  1. Configure Claude Code to use Amazon Bedrock (models in settings.local.json with us.anthropic.* IDs)
  2. Run in --print mode: claude --print --output-format json --max-turns 100 - (stdin prompt)
  3. Observe 400 x-anthropic-billing-header is a reserved keyword and may not be used in the system prompt.
  4. Confirm in ~/.claude/debug/<session-id>.txt that the billing header was generated and ANTHROPIC_CUSTOM_HEADERS present: false

The error is somewhat intermittent — the billing header hash changes between requests, and not every request triggers the rejection. In my testing, the first request in a session (typically a token-counting call to Haiku) often succeeds, while the main model request fails.

Workarounds Attempted (None Effective)

| Workaround | Result |
|---|---|
| CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1 | No effect — billing header injection is not gated by this flag |
| ENABLE_TOOL_SEARCH=0 | No effect — tool search was already auto-disabled in failing sessions |
| Stripping ANTHROPIC_CUSTOM_HEADERS from env | No effect — the header is generated internally, not from env |
| ANTHROPIC_CUSTOM_HEADERS was already false | Confirmed in debug logs |

modelList Configuration

{
  "modelList": [
    {"id": "us.anthropic.claude-opus-4-6-v1", "name": "Claude Opus 4.6", "provider": "bedrock"},
    {"id": "global.anthropic.claude-opus-4-5-20251101-v1:0", "name": "Claude Opus 4.5", "provider": "bedrock"},
    {"id": "global.anthropic.claude-sonnet-4-5-20251101-v1:0", "name": "Claude Sonnet 4.5", "provider": "bedrock"},
    {"id": "global.anthropic.claude-haiku-4-5-20251101-v1:0", "name": "Claude Haiku 4.5", "provider": "bedrock"}
  ]
}

Claude Model

Opus 4.6 (Bedrock: us.anthropic.claude-opus-4-6-v1)

Is this a regression?

I don't know — the billing header appears to have been present since at least v2.1.29 based on debug logs.

Claude Code Version

2.1.37

Platform

Amazon Bedrock

Operating System

macOS (Darwin 25.2.0)

Terminal/Shell

CLI (--print mode, non-interactive)

View original on GitHub ↗

11 Comments

taquaki-satwo · 6 months ago

Hello. I also use macOS.
The same issue occurred in 2.1.36, but not in 2.1.34.

# Remove existing installation
rm -f ~/.local/bin/claude
rm -rf ~/.local/share/claude

curl -fsSL https://claude.ai/install.sh | bash -s 2.1.34

I set DISABLE_AUTOUPDATER in settings.json to disable automatic updates.
ref. https://code.claude.com/docs/en/setup#disable-auto-updates

meetamit · 6 months ago

I encountered the same issue and also worked around it by rolling back to v2.1.34. If you're still using NPM to install Claude Code, then the fix is:

  1. Verify that you have a "broken" version:

1a. Run npm list --global
1b. If you see @anthropic-ai/claude-code@2.1.37 or 2.1.36 then you've got a broken version.

  1. Roll back to a slightly older version: npm install -g @anthropic-ai/claude-code@2.1.34
John867530nine · 6 months ago

Resolved in my containerized instance by breaking the header, like this:

RUN find /usr/local/lib/node_modules/@anthropic-ai/claude-code -name "*.js" \
-exec grep -l "x-anthropic-billing-header" {} \; \
-exec sed -i 's/x-anthropic-billing-header/x-anthropic-billing-removed/g' {} \;

robincohen · 6 months ago

I hit this same issue. The following workaround fixed it for me:

Workaround:
Add to ~/.bashrc:
export CLAUDE_CODE_ATTRIBUTION_HEADER=0

Suggestion:
Claude Code should automatically disable attribution headers when CLAUDE_CODE_USE_BEDROCK=1 is set, or provide better error messaging for this scenario.

jonathanhle · 6 months ago
I hit this same issue. The following workaround fixed it for me: Workaround: Add to ~/.bashrc: export CLAUDE_CODE_ATTRIBUTION_HEADER=0 Suggestion: Claude Code should automatically disable attribution headers when CLAUDE_CODE_USE_BEDROCK=1 is set, or provide better error messaging for this scenario.

thank you for the workaround @robincohen !!!!!!

szwang · 6 months ago

Thank you so much for reporting! So sorry for the friction here, there was a bug specifically in our Opus 4.1 deployment on Bedrock and it should be fixed now. @robincohen @jonathanhle would you mind trying again without setting CLAUDE_CODE_ATTRIBUTION_HEADER=0?

szwang · 6 months ago

Closing but please tag me if you're still encountering this!

robincohen · 6 months ago

Sorry for the slow response. I am set up to run on govcloud with sonnet 4.5 so I don’t believe we have Opus yet. I thought the issue was in Claude code. I tried update Claude code to version 2.1.49 and removing my CLAUDE_CODE_ATTRIBUTION_HEADER=0I still get the same error. I assume this means there were no changes in the CLI. RobinSent from my iPhoneOn Feb 20, 2026, at 2:01 PM, Suzanne Wang @.***> wrote:szwang left a comment (anthropics/claude-code#24168)
Closing but please tag me if you're still encountering this!

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you were mentioned.Message ID: @.***>

OldRoach · 6 months ago

This is still NOT WORKING on GovCloud's Bedrock environment. I tried regressing to the older version of Claude Code without success, I added the CLAUDE_CODE_ATTRIBUTION_HEADER=0 to the .bashrc file. We don't have access to the Opus models only Sonnet.

I have had no success with any of the recommended solutions or work arounds to date. FYI - Roo Code still works to hit the sonnet model. Additional suggestions welcomed,

robincohen · 6 months ago

@OldRoach regarding the workaround of adding the CLAUDE_CODE_ATTRIBUTION_HEADER=0 to the .bashrc not working… Did you source the updated .bashrc or open a new bash shell? Apologies if that’s too obvious. It’s just that this workaround definitely works for me.

github-actions[bot] · 5 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.