nginx protocol_error ai_generated true

upstream sent chunked transfer encoding while sending Content-Length header, client: 10.0.0.1, server: example.com

ID: nginx/upstream-sent-http-1-1-chunked-with-content-length

Also available as: JSON · Markdown · 中文
82%Fix Rate
87%Confidence
1Evidence
2024-01-10First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
nginx 1.20.2 active
nginx 1.22.1 active
nginx 1.24.0 active
nginx 1.26.0 active

Root Cause

Upstream server sends conflicting HTTP headers: both Content-Length and Transfer-Encoding: chunked, violating HTTP/1.1 spec.

generic

中文

上游服务器发送了冲突的 HTTP 头:同时包含 Content-Length 和 Transfer-Encoding: chunked,违反了 HTTP/1.1 规范。

Official Documentation

https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_hide_header

Workarounds

  1. 85% success Fix the upstream application to not send both Content-Length and Transfer-Encoding headers. For example, in a Python Flask app, remove the Content-Length header when using chunked encoding: @app.after_request def remove_conflicting_headers(response): if response.headers.get('Transfer-Encoding') == 'chunked': response.headers.pop('Content-Length', None) return response
    Fix the upstream application to not send both Content-Length and Transfer-Encoding headers. For example, in a Python Flask app, remove the Content-Length header when using chunked encoding:
    @app.after_request
    def remove_conflicting_headers(response):
        if response.headers.get('Transfer-Encoding') == 'chunked':
            response.headers.pop('Content-Length', None)
        return response
  2. 75% success Use nginx's proxy_hide_header directive to remove the conflicting Content-Length header from upstream responses: proxy_hide_header Content-Length; This forces nginx to rely on chunked encoding alone.
    Use nginx's proxy_hide_header directive to remove the conflicting Content-Length header from upstream responses:
    proxy_hide_header Content-Length;
    This forces nginx to rely on chunked encoding alone.

中文步骤

  1. Fix the upstream application to not send both Content-Length and Transfer-Encoding headers. For example, in a Python Flask app, remove the Content-Length header when using chunked encoding:
    @app.after_request
    def remove_conflicting_headers(response):
        if response.headers.get('Transfer-Encoding') == 'chunked':
            response.headers.pop('Content-Length', None)
        return response
  2. Use nginx's proxy_hide_header directive to remove the conflicting Content-Length header from upstream responses:
    proxy_hide_header Content-Length;
    This forces nginx to rely on chunked encoding alone.

Dead Ends

Common approaches that don't work:

  1. Set proxy_http_version 1.0; 70% fail

    HTTP/1.0 does not support chunked encoding, but the upstream may still send conflicting headers; this can cause other issues like connection close.

  2. Disable chunked transfer with proxy_set_header Transfer-Encoding ''; 90% fail

    This removes the header from the request to upstream, not the response; the error is about the response from upstream.

  3. Increase proxy_buffer_size 95% fail

    Buffer size does not affect header parsing or protocol compliance; the error is a protocol violation, not a buffer overflow.