Claude Code v2.1.239 shipped on August 21, 2026 with a one-line fix that any team running Claude Code against Amazon Bedrock through a proxy needs to read twice: the release, in Anthropic’s words, “Fixed Bedrock streaming behind proxies that strip the response Content-Type header, which silently doubled billed API calls by re-running every turn non-streaming.” A gateway that dropped one HTTP header turned every conversational turn into two billed requests, and nothing in the session told you.
The phrase that matters is “silently”. Anthropic’s own Bedrock documentation already describes a different, louder failure for the same header when a proxy rewrites it rather than strips it: Claude Code refuses the response and prints a named error. The stripped case took the other branch, fell back to a non-streaming re-run, and billed the turn twice. On Bedrock there is no Anthropic dashboard to catch that for you. Claude Code sends no metrics from your cloud back to Anthropic, so the only evidence lives in your AWS bill and your own gateway logs.
This post does three things. It explains, from AWS’s own API reference, why a single header carries so much weight on Bedrock streaming. It puts the loud and the silent failure side by side in one table, a comparison Anthropic’s own documentation does not make, because the two halves are published on different pages. And it turns the documented facts into an audit method and a gateway header checklist you can run against your own deployment today, whether or not you have upgraded yet.
- 01The billing consequence is Anthropic’s wording, not ours.The v2.1.239 changelog says the bug “silently doubled billed API calls by re-running every turn non-streaming.” That is the vendor characterising its own defect, scoped to each affected turn. No affected-version range, introduction date, user count or dollar impact has been published.
- 02Same header, two failure modes, only one of them loud.A proxy that rewrites Content-Type to something else trips a named error that Anthropic documents in its Bedrock troubleshooting guide. A proxy that strips the header entirely took a silent non-streaming fallback until v2.1.239. The difference is the whole story.
- 03On Bedrock, the audit trail is yours alone.Claude Code does not send usage metrics from cloud-provider deployments back to Anthropic, so the analytics dashboards and Analytics API do not cover Bedrock. Double execution shows up only in your AWS bill, your OpenTelemetry export or your gateway logs.
- 04Cost-relevant gateway fixes have landed at least three times this year.A June 17 release (v2.1.181) fixed gateway prompt caching with one documented root cause; an August 20 release (v2.1.237) fixed gateway prompt caching again with no stated cause; August 21 fixed Bedrock streaming. Those are the three we can name from the changelog, not an audit of every 2026 entry. Header pass-through fidelity is a standing operational requirement, not a one-off.
- 05The /cost change in the same release is a display fix.Cost estimates in /cost, the status line and --max-budget-usd now include the 1.1× US-only-inference premium for data-residency workspaces. The premium itself is Anthropic’s standing pricing policy, applies to the Claude API and Claude Platform on AWS, and does not apply to Bedrock.
01 — What ShippedOne line among roughly forty-five.
v2.1.239 was the sixth Claude Code version in five days. Anthropic shipped v2.1.234 on August 17 and one or two versions every day through August 21, a cadence we covered in the Aug 18 operator-changes post for v2.1.234 and v2.1.235, so we will not restate those items here. The August 21 entry is long; counting the bulleted items under its heading in the published changelog gives roughly forty-five fixes and additions, most of them small. The Bedrock fix is one bullet among them, and it is the one that touches money.
“Fixed Bedrock streaming behind proxies that strip the response Content-Type header, which silently doubled billed API calls by re-running every turn non-streaming.”— Claude Code changelog, v2.1.239 entry, August 21, 2026
Read it as three claims. First, the trigger: a proxy between Claude Code and Bedrock that strips the response Content-Type header. Second, the behaviour: Claude Code re-ran every turn non-streaming. Third, the consequence: billed API calls doubled, silently. The third claim is the one worth pausing on, because an entry of this kind could easily have stopped at the mechanism and left the billing effect to be inferred by the reader. This one does not. We therefore treat “doubled” as the vendor’s own characterisation, scoped to each affected turn, and not as a statement about anyone’s total spend.
What the entry does not say is as important. There is no affected version range, no date the regression was introduced, no count of affected workspaces and no dollar figure. We looked for an earlier public report of this exact symptom in the anthropics/claude-code issue tracker, dated on or before August 21, and a targeted search surfaced only unrelated Bedrock issues. That is a narrow statement about one search, not proof that nobody noticed; it does mean this post cannot attribute the discovery to a reporter or a date, and neither should anyone else.
02 — MechanismWhy one header carries the whole streaming contract.
To see why a stripped Content-Type is enough to change behaviour, start with how Bedrock streaming works at the HTTP layer. Claude Code talks to Bedrock through the Invoke API pair, InvokeModel for non-streaming and InvokeModelWithResponseStream for streaming; Anthropic’s Bedrock docs state that Claude Code does not support the Converse API. AWS’s API reference for the streaming call says the response content type is always set to application/vnd.amazon.eventstream, with a separate header, x-amzn-bedrock-content-type, carrying the actual content type of the payload inside the stream.
So the outer Content-Type is not decoration. It is the signal that the body is a binary AWS event stream rather than a JSON document, and it is the one header in the exchange that every generic proxy framework understands and feels entitled to touch. The Bedrock-specific headers, x-amzn-bedrock-accept on the request and x-amzn-bedrock-content-type on the response, are names a general-purpose gateway was never written to preserve or even recognise. A proxy config that normalises outer headers for every upstream will do to a Bedrock stream exactly what it does to everything else, and the stream is the one upstream that cannot tolerate it.
Content-Type on the response
The header the v2.1.239 fix is about. Generic proxies understand it, which is why they touch it. Stripped: silent non-streaming re-run before v2.1.239. Rewritten: a named rejection error in v2.1.208 and later.
x-amzn-bedrock-content-type
AWS adds this so the client can learn what is inside the event stream. Anthropic’s docs do not describe what Claude Code does if a proxy drops it, so treat it as a risk to test, not a documented failure.
Accept and x-amzn-bedrock-accept
AWS’s sample streaming request sets an HTTP accept of application/vnd.amazon.eventstream alongside a Bedrock-layer x-amzn-bedrock-accept. Two accept headers at two layers is exactly the kind of contract a one-size proxy rule flattens.
One more documented fact rules out a tempting alternative explanation. Anthropic’s IAM guidance for Claude Code on Bedrock lists bedrock:InvokeModel and bedrock:InvokeModelWithResponseStream as two distinct permissions. Streaming and non-streaming are separate authorised actions at the AWS layer. In our reading, a role missing one of them would surface as a permission error, not a quiet fallback, which is why this bug is a proxy-transport problem rather than an IAM problem. Anthropic’s changelog does not explain why an absent header took a silent code path while a wrong header takes a loud one, and we are not going to guess at Claude Code’s internal branching. The documented behaviours are enough to work with.
03 — Two Failure ModesRewritten is loud. Stripped was silent.
This is the comparison Anthropic’s own pages do not make, because the two halves live on different pages. The loud failure is in the troubleshooting section of Claude Code’s Amazon Bedrock documentation. The silent one is in the changelog. Put side by side, they describe two branches of the same fragility: Claude Code checks that a Bedrock streaming response carries the event-stream content type, and what happens next depends on whether the header is wrong or missing.
| Header state and version | What Claude Code does | What you see | Billing effect | Where Anthropic documents it |
|---|---|---|---|---|
| Content-Type present but rewritten to a different value | ||||
| v2.1.208 and later | Rejects the successful streaming response because it reports a content type other than the event stream, rather than decoding a body it cannot read | An error beginning Bedrock streaming response has content-type | Loud failure. No doubled call is documented for this branch | Bedrock docs, Troubleshooting: “Streaming errors behind a gateway or proxy” |
| Before v2.1.208 | Buffers the full response, then fails while decoding it | API Error: Truncated event message received | Not documented for this branch | Same troubleshooting section, described as the pre-v2.1.208 symptom |
| Content-Type stripped entirely | ||||
| Before v2.1.239 | Re-ran every turn non-streaming | Nothing in the session. The changelog’s word is “silently” | “Silently doubled billed API calls”, per the changelog, on each affected turn | Changelog, v2.1.239 entry, August 21, 2026 |
| v2.1.239 and later | Fixed, per the changelog. No further detail on the new behaviour is published | Streaming behind the same proxy is described as working | No doubled call. Exposure before the upgrade is yours to audit | Changelog, v2.1.239 entry |
Two details from the loud branch are worth carrying forward. The docs name the common real-world shape of the rewrite, an Amazon API Gateway and Lambda integration that re-emits the stream as server-sent events, which turns the content type into text/event-stream. That example is documented for the rewrite case only; Anthropic does not say what produced the stripped header in the silent case, and we will not extend the example to cover it. And the docs provide a deliberate escape hatch for the rewrite case, covered in the callout below, which has no documented counterpart for the stripped case because the fix for that one is simply the upgrade.
CLAUDE_CODE_DISABLE_BEDROCK_CONTENT_TYPE_GUARD=1 skips the check that a Bedrock streaming response carries the application/vnd.amazon.eventstream content type. Anthropic’s environment-variable reference says to set it only when the gateway rewrites the header but passes the binary event-stream body through unmodified. If the body is also transformed, disabling the guard brings back the truncation failure. It is a tool for the rewrite branch of the table, not a workaround for the stripped one.
04 — The Visibility GapOn Bedrock, nobody is watching this for you.
The reason a doubled call could stay silent is structural, and Anthropic documents it plainly in its cost-management guide. On cloud-provider deployments, Claude Code sends no metrics back to Anthropic. The analytics dashboards and the Claude Code Analytics API that first-party customers use to watch spend do not cover Bedrock usage at all. There was no vendor-side counter that could have flagged a two-to-one ratio of requests to turns, because the vendor never saw the requests.
“Claude Code does not send metrics from your cloud back to Anthropic, so the analytics dashboards and the Claude Code Analytics API do not cover this usage.”— Claude Code documentation, Manage costs effectively, Cloud providers
The same guide lists what you do have. For per-user attribution on a cloud provider it names three paths: OpenTelemetry export from Claude Code itself, a self-hosted Claude apps gateway, or a third-party LLM gateway. It names LiteLLM as an example of the third, describing it as an open-source tool that tracks spend by key, and in the same breath states that the project is unaffiliated with Anthropic and has not been audited for security. Add the AWS bill itself and you have the surfaces on which double execution could ever have been visible. The grid below sets them beside the one place it never showed at all.
The AWS bill
Always present, never granular. It tells you the month cost more than the number of turns implied, and nothing about which sessions or which proxy path. Useful for sizing, useless for diagnosis.
OpenTelemetry export
Anthropic’s documented path for per-user cost attribution on cloud providers. Emitted by Claude Code itself, so it carries the client-side view of each turn. Pair it with the gateway view and the ratio falls out.
Gateway logs
Two of Anthropic’s three named paths land here: a self-hosted Claude apps gateway and a third-party LLM gateway such as LiteLLM both log every upstream request. This is the surface most likely to see both the streaming and the non-streaming call on the same turn.
The session itself
Nothing. The changelog’s word is “silently”. Anthropic documents no in-session indicator that a turn was re-run, which is why the audit has to happen at the gateway rather than in the terminal.
This is the same shape of problem we described in the GitHub Copilot credit-billing audit: the vendor’s own meter is the wrong instrument when the metered thing happens somewhere the vendor cannot see. On Bedrock that is by design. Anthropic’s position is that cloud-provider usage is yours to observe, and the documentation hands you the three tools and steps back.
05 — DetectionDetecting double execution from gateway logs.
Because no affected-version range is published, the only honest way to know whether your deployment paid twice is to look. The method below is our synthesis of the documented facts: Claude Code uses exactly two Bedrock operations, those operations are distinct actions at the AWS layer, the bug re-ran each turn non-streaming, and Anthropic has no view of any of it. Everything else is ordinary log analysis.
Step 1: scope the search to the Invoke pair
Claude Code does not use the Converse API, so you are only looking for InvokeModelWithResponseStream and InvokeModel. If your gateway logs the operation name or the target path, filter to those two. Anything else in the Bedrock log is not Claude Code traffic, or at least not this bug.
Step 2: look for the streaming and non-streaming mix
A healthy Claude Code session on Bedrock is overwhelmingly streaming. The signature of the bug is a streaming request followed closely by a non-streaming request for the same model, from the same client, with a near-identical payload size. If your gateway assigns request IDs and records the client or session identity, pair them: one turn should map to one upstream call. Two upstream calls per turn, one of each kind, is the pattern the changelog describes.
Step 3: confirm the trigger at the proxy edge
Capture a Bedrock streaming response on the client side of your proxy. Per AWS, the upstream always sets Content-Type: application/vnd.amazon.eventstream. If the header reaches Claude Code rewritten, you are in the loud branch and would already have seen the error. If it reaches Claude Code absent, you were in the configuration the fix describes, and every pre-upgrade session through that proxy is in scope.
Step 4: reconcile with the client-side view
If you export OpenTelemetry from Claude Code, count turns there and compare with upstream requests at the gateway over the same window. A ratio near two on the streaming paths is the finding. A ratio near one means the proxy was passing the header, or the sessions predate whatever introduced the fallback, which, again, Anthropic has not dated.
Streaming followed by non-streaming, same turn
The direct fingerprint of the documented behaviour. Requires a gateway that logs the operation and some client or session identity. Any AWS-side log that records the API action can serve the same purpose if it carries enough context to group requests by session.
Upstream requests ≈ 2× client-side turns
Works without per-request pairing. Noisier, because retries and tool-use loops also inflate the upstream count, so confirm with Signal A before concluding anything.
Content-Type absent on streaming responses at the edge
Proves the trigger existed, not that the fallback fired. Pair it with A or B. If the header is present and correct today, check whether the proxy config changed before assuming it was always fine.
A note on what this audit cannot do. It can show that double execution happened on your deployment and bound the window to when the proxy was stripping the header. It cannot tell you which Claude Code version introduced the fallback, because that is unpublished, and it cannot distinguish a pre-fix doubled turn from an ordinary client retry without the pairing in Signal A. Treat the numbers it produces as evidence for a conversation with your AWS account team, not as a settled figure.
06 — Header ChecklistThe headers a gateway must pass through untouched.
Anthropic’s documentation scatters the header requirements for a gateway-fronted Claude Code across three pages: the Bedrock guide, the environment-variable reference and the LLM gateway guide. The table below gathers them into one checklist. Where Anthropic does not document what happens when a header is dropped, the cell says so, because an undocumented failure is a risk to test rather than a fact to cite.
| Header | What it controls | If a proxy drops or rewrites it | Related setting |
|---|---|---|---|
| Bedrock path: Claude Code → proxy → Amazon Bedrock | |||
Content-Type (response) | Tells Claude Code the body is an AWS binary event stream. Always application/vnd.amazon.eventstream from Bedrock, per AWS | Rewritten: named error in v2.1.208 and later. Stripped: silent non-streaming re-run and doubled billed calls before v2.1.239, per the changelog | CLAUDE_CODE_DISABLE_BEDROCK_CONTENT_TYPE_GUARD (rewrite case only, body must pass through intact) |
Accept and x-amzn-bedrock-accept (request) | Requests the streaming response shape at the HTTP layer and the Bedrock layer respectively, per AWS’s sample request | Not documented by Anthropic. Treat as a risk to test: capture what your proxy forwards and compare with AWS’s sample | ANTHROPIC_BEDROCK_BASE_URL is where the gateway is configured; no header-specific toggle is documented |
| Authorization and AWS SigV4 signing headers | Who signs the Bedrock request. A gateway that authenticates on Claude Code’s behalf replaces these | A signing or permission mismatch surfaces as an authentication error, not a silent fallback, in our reading of the IAM guidance. Loud, so it is not this bug | CLAUDE_CODE_SKIP_BEDROCK_AUTH when the gateway handles AWS auth; a separate CLAUDE_CODE_SKIP_MANTLE_AUTH exists for the Mantle endpoint |
| Gateway path: Claude Code → LLM gateway → Anthropic API | |||
anthropic-beta | Carries capability flags, including the OAuth capability the gateway guide says must be forwarded to Anthropic | Per the gateway guide, a gateway that does not forward a capability Claude Code adds with a release breaks the corresponding features | Gateway configuration behind ANTHROPIC_BASE_URL. Consult the request-headers reference the guide points to |
Where does a stripped header come from in practice? The honest answer is that Anthropic does not say, and we are not going to name a product. What the primary documentation does let us rule out is the defaults of the two most common layers. nginx’s proxy_set_header documentation lists only Host and Connection as the headers it rewrites by default, plus a set of caching-conditional headers when caching is enabled; Content-Type is not among them, so an nginx strip implies an explicit override or a body-rewriting module. AWS’s Application Load Balancer header documentation concerns the X-Forwarded-* family and documents no default Content-Type rewriting. The one concrete example Anthropic gives, the API Gateway and Lambda re-emit, is for the rewrite branch. Anything more specific is a guess.
07 — RecurrenceNot the first gateway fix to touch cost this year.
The Bedrock fix is the most expensive-sounding entry, but it is not the first time in 2026 that the changelog has recorded a fix to cost-relevant behaviour for sessions running through a gateway or a custom base URL. Two prompt-caching fixes for such sessions sit earlier in the same changelog, sixty-four days apart, one with a documented cause and one with no cause stated at all. Those are the entries we can name rather than a tally: we have not audited every 2026 release for cost-relevant gateway fixes, so read three as a floor. Laid out in order, they make the case that header and request fidelity through an intermediary is a standing operational requirement rather than a one-off bug.
v2.1.181
Changelog: fixed prompt caching not reading on a custom ANTHROPIC_BASE_URL and on Foundry, caused by a per-request attestation token changing every turn. A documented root cause: a value that should have been stable across turns was not, and every cache key missed.
v2.1.237
The complete changelog text is “Fixed prompt caching for sessions using an LLM gateway or custom base URL.” No root cause is stated. A fix implies prior breakage, but nothing confirms it shares the June mechanism, and we do not assume it does.
v2.1.239
The subject of this post. A different feature and a different header: an intermediary altered the exchange, Claude Code degraded silently, and this time the changelog states the cost outright rather than leaving it implied.
Anthropic’s gateway guide is candid about why this keeps happening. It states that gateways passing traffic on to Anthropic must forward the OAuth capability in the anthropic-beta header, and it warns that a gateway which does not forward the new capabilities Claude Code adds with each release breaks the corresponding features. It also disclaims the whole category: Anthropic does not endorse, maintain or audit third-party gateway products. Responsibility for fidelity sits with whoever operates the intermediary. That is a reasonable position, and it is also exactly why the audit in section 05 has to be yours.
One adjacent cost vector belongs in the same conversation. The cost guide notes that prompt caching defaults to a five-minute TTL on an API key or cloud provider, against one hour on a subscription. A gateway that buffers or delays requests can therefore cause cache misses on Bedrock independently of any header bug. If your gateway audit is already open, check cache-read rates while you are in there. We wrote up the design side of this, how a gateway is supposed to preserve request fidelity in the first place, in our LLM gateway architecture reference, and the generic double-execution discipline in the webhook idempotency reference. A fallback path that re-runs work without an idempotency key is the same bug whether it lives in a webhook consumer or inside an agent’s own HTTP client.
08 — The /cost ChangeA display fix that reads like a price rise.
The same v2.1.239 release carries a second cost line that is easy to misread: “Cost estimates (/cost, status line, --max-budget-usd) now include the 1.1× US-only-inference premium for data-residency workspaces.” That is the complete entry. It changes what three estimate surfaces show. It does not change what anyone is charged, and it applies to a different deployment surface from the Bedrock bug.
The premium itself predates the release and is documented independently on Anthropic’s data-residency page: US-only inference, selected with inference_geo: "us", is priced at 1.1× the standard rate across input tokens, output tokens, cache writes and cache reads. It applies to Claude 4.6 and later models; earlier models return a 400 on the parameter. The page says the same multiplier applies to Microsoft Foundry deployments using the US Data Zone Standard type, and that Amazon Bedrock and Google Cloud have their own regional pricing, which puts Bedrock outside this multiplier entirely.
US-only inference rate
Applied across all four token categories per the data-residency page. Claude API and Claude Platform on AWS, plus Foundry US Data Zone Standard. Not Bedrock, not Google Cloud.
inference_geo support
Only Claude 4.6-and-later models accept the parameter. The documentation lists Opus 4.5, Sonnet 4.5 and Haiku 4.5 among the models that return a 400 if it is sent.
/cost · status line · --max-budget-usd
The three estimate surfaces the changelog names. All three now include the premium. Anthropic’s word is that they “now include” it; nothing published characterises what they showed before, so we treat the prior display as unstated.
Two cautions on how to describe this. The changelog says the estimates “now include” the premium; it does not say the prior estimates were wrong, and no second source characterises the previous display, so we write it the way Anthropic does. And the premium has a capacity side as well as a price side: the data-residency page states that under a Priority Tier commitment each token consumed with inference_geo: "us" draws down 1.1 tokens from the committed throughput. If the estimates previously excluded the premium, which is the natural reading of “now include” though not something Anthropic states outright, a --max-budget-usd cap tuned against them on a data-residency workspace would trip after about nine percent fewer tokens once upgraded, since a fixed dollar cap divided by a 1.1× estimate buys 1/1.1 of the tokens. What is actually spent does not change.
09 — What To Do NowFour deployments, four different actions.
The right response depends on where Claude Code sits in your stack. The upgrade is the same for everyone; the audit and the follow-through are not.
No proxy between Claude Code and Bedrock
The changelog scopes the bug to proxies that strip the header, and AWS always sets it. Upgrade to v2.1.239 on schedule. Spend the audit time on cache-read rates instead; the five-minute cloud-provider TTL is the cost lever you control.
Proxy or gateway in the Bedrock path
Upgrade now, then run section 05 against pre-upgrade logs and section 06 against the live config. Capture the response Content-Type at the edge. If it was absent, size the window and take it to your AWS account team with the pairing evidence.
First-party with inference_geo set
The Bedrock bug does not apply. The /cost change does: estimates now include the 1.1× premium, which is Anthropic’s standing pricing policy rather than a new charge. Re-check any --max-budget-usd cap tuned against pre-upgrade estimates before the first long session on the new version.
Native Anthropic API shape on Bedrock
Unconfirmed either way. The changelog says “Bedrock streaming”; Anthropic documents Mantle as a separate endpoint with its own base-URL override and its own skip-auth variable, and does not say whether the fix covers it. Audit as if it might and do not assume it does.
Beyond this one bug, the durable lesson is the one we keep coming back to in our AI cost-optimisation discipline: the meter you trust has to be on the side of the boundary where the money leaves. For Bedrock that is your gateway and your AWS account, and it needs to be instrumented before the next silent fallback, not after. Teams that already run Claude Code’s auto mode on Bedrock, which we covered when the classifier defaults reached Bedrock, Vertex and Foundry, have the most turns per session and the most to gain from pairing OpenTelemetry with gateway logs. If you want that instrumentation designed rather than improvised, our AI transformation engagements start from the billing boundary, and our analytics practice builds the reconciliation that keeps the two counts honest.
10 — ConclusionThe bug is fixed. The blind spot is not.
One header, two code paths, and only one of them made a sound.
Claude Code v2.1.239 closes a defect that Anthropic describes in its own words as silently doubling billed API calls by re-running every turn non-streaming when a proxy stripped the response Content-Type header. The fix is one line. The reason it took a changelog entry to surface is that on Bedrock, Anthropic sees none of your traffic, and the fallback announced itself to nobody.
What is not in the changelog is as instructive as what is. No version range, no introduction date, no user count, no dollar figure, and no named culprit. Every one of those gaps is an invitation to invent, and the right response is the opposite: scope the search to the Invoke pair, look for the streaming and non-streaming mix, confirm the header at the edge, and reconcile with the client-side count. That audit is worth running once even if it finds nothing, because it leaves you with the instrumentation the next gateway fix will need.
The recurrence is the real story. At least three times this year the changelog has recorded a cost-relevant fix for sessions that run through a gateway or custom base URL, and Anthropic’s position, stated plainly, is that fidelity through an intermediary is the operator’s job. The teams that come out ahead are the ones that treat header pass-through as a tested property of their deployment rather than an assumption, and that keep a meter on the side of the boundary where the money actually leaves.