Skip to content

extproc: send content-length as a decimal string on retried requests - #2944

Open
3431481073 wants to merge 1 commit into
theagentrouter:mainfrom
3431481073:fix/2930-content-length-format
Open

3431481073 wants to merge 1 commit into
theagentrouter:mainfrom
3431481073:fix/2930-content-length-format

Conversation

@3431481073

Copy link
Copy Markdown

Description

On a retry the upstream ext_proc replaces the request body, so Envoy clears content-length and restamps it from dynamic metadata. buildContentLengthDynamicMetadataOnRequest stored the length as a NumberValue, and Envoy renders a double in shortest form when substituting %DYNAMIC_METADATA(io.envoy.ai_gateway:content_length)%. A 100000-byte body therefore went out as content-length: 1e+05, and strict HTTP parsers such as uvicorn/vLLM rejected the request with 400 Invalid HTTP request received. Only retries were affected; the first attempt kept the client's content-length: 100000.

Store the length as a decimal string (strconv.Itoa) instead. Envoy then substitutes plain digits, so the retry carries the same header value as the original request.

Related Issues/PRs

Fixes #2930

Special notes for reviewers

Only the dynamic metadata value type changes. The header mutation filter that consumes it is unchanged and substitutes the string verbatim. A repository search found no other reader of the content_length metadata key.

Test_buildContentLengthDynamicMetadataOnRequest covers 0, 1, 1000, 99999, 100000 and 32000000. Test_chatCompletionProcessorUpstreamFilter_ProcessRequestHeaders_contentLength exercises the request-header phase a retry re-runs with a 100000-byte body.

go test ./internal/extproc/ ./internal/extensionserver/ -count=1 and go vet ./internal/extproc/ pass. End-to-end Envoy + vLLM was not available in this environment.

buildContentLengthDynamicMetadataOnRequest stored the request body length
as a NumberValue. On retries the header mutation filter substitutes
%DYNAMIC_METADATA(...:content_length)%, and Envoy renders a double in
shortest form, so a round length like 100000 went out as 1e+05. Strict
HTTP parsers (uvicorn/vLLM) reject that with 400.

Store the length with strconv.Itoa so the retry sends plain decimal
digits. Add unit tests for the metadata builder and for the request
header path a retry re-runs, using a 100000-byte body.

Fixes theagentrouter#2930

Signed-off-by: xby <3431481073@qq.com>
@3431481073
3431481073 requested a review from a team as a code owner October 29, 2026 16:04
@netlify

netlify Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for theagentrouter canceled.

Name Link
🔨 Latest commit f4353fe
🔍 Latest deploy log https://app.netlify.com/projects/theagentrouter/deploys/6ae36e9a6451c5d4e1b28e8e

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Retries send content-length: 1e+0N when the request body length is a round number

1 participant