Current Behavior
When nginx_config.http.client_max_body_size is set to 0 (documented as "no limit", and also the default value), APISIX rejects every request that uses Transfer-Encoding: chunked with 413 Request Entity Too Large — regardless of the actual body size. Even a 1-byte chunked body is rejected immediately.
Requests carrying a Content-Length header are handled correctly: with client_max_body_size: 0 they pass through at any size (tested up to 300 MB).
This deviates from stock nginx semantics, where client_max_body_size 0; disables the body size check for both sized and chunked requests.
Real-world impact: docker push streams blob uploads (PATCH /v2/<name>/blobs/uploads/<uuid>) with chunked transfer encoding, so any container registry (e.g. Harbor) behind APISIX 3.17 with the default body size setting fails with 413 on every push. The apisix-helm-chart 2.16.0 renders client_max_body_size: 0 by default, so a default Helm installation is affected out of the box.
Setting an explicit non-zero value (e.g. 1g) restores correct behavior for chunked requests.
Expected Behavior
client_max_body_size: 0 should mean "unlimited" for chunked requests as well, consistent with the Content-Length case and with nginx's documented behavior.
Error Logs
Nothing is written to the error log. The access log shows the 413 being generated by APISIX itself with no upstream involved:
172.17.0.1 - - [13/Jul/2026:09:20:11 +0000] 127.0.0.1:19080 "POST /anything HTTP/1.1" 413 255 0.000 "-" "curl/8.7.1" - - - "http://127.0.0.1:19080"
Response:
< HTTP/1.1 413 Request Entity Too Large
< Server: APISIX/3.17.0
Steps to Reproduce
config.yaml (standalone mode, minimal):
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
apisix:
node_listen: 9080
nginx_config:
http:
client_max_body_size: 0
apisix.yaml (any upstream works; it is never reached for chunked requests):
routes:
-
uri: /*
upstream:
nodes:
"127.0.0.1:9180": 1
type: roundrobin
#END
- Run APISIX:
docker run -d --name apisix-413 -p 19080:9080 \
-v $PWD/config.yaml:/usr/local/apisix/conf/config.yaml:ro \
-v $PWD/apisix.yaml:/usr/local/apisix/conf/apisix.yaml:ro \
apache/apisix:3.17.0-debian
- Send the same 5-byte body with and without chunked encoding:
printf 'hello' > body.bin
# Content-Length request -> passes through (502 because the dummy upstream is dead)
curl -s -o /dev/null -w '%{http_code}\n' -X POST \
--data-binary @body.bin http://127.0.0.1:19080/anything
# => 502
# chunked request -> rejected by APISIX before reaching the upstream
curl -s --http1.1 -o /dev/null -w '%{http_code}\n' -X POST \
-H 'Transfer-Encoding: chunked' --data-binary @body.bin http://127.0.0.1:19080/anything
# => 413
- Change
client_max_body_size to 1g and restart: the chunked request now returns 502 (passes through) as expected.
Notes:
- Removing
nginx_config.http.client_max_body_size entirely reproduces the same 413, so the default configuration is affected too.
- Reproduced over both HTTP/1.1 and HTTP/2 (TLS), any method (GET/POST/PATCH), any route.
Environment
- APISIX version: 3.17.0 (official image
apache/apisix:3.17.0-debian, also deployed via apisix-helm-chart 2.16.0)
- Operating system: Docker 29.4.0 on Windows 11 (also reproduced on Kubernetes/containerd on Linux)
- OpenResty / Nginx version: bundled with the 3.17.0 image (
Server: APISIX/3.17.0)
- etcd version: n/a (standalone mode; also reproduced with etcd 3.5 in the Helm deployment)
Current Behavior
When
nginx_config.http.client_max_body_sizeis set to0(documented as "no limit", and also the default value), APISIX rejects every request that usesTransfer-Encoding: chunkedwith413 Request Entity Too Large— regardless of the actual body size. Even a 1-byte chunked body is rejected immediately.Requests carrying a
Content-Lengthheader are handled correctly: withclient_max_body_size: 0they pass through at any size (tested up to 300 MB).This deviates from stock nginx semantics, where
client_max_body_size 0;disables the body size check for both sized and chunked requests.Real-world impact:
docker pushstreams blob uploads (PATCH /v2/<name>/blobs/uploads/<uuid>) with chunked transfer encoding, so any container registry (e.g. Harbor) behind APISIX 3.17 with the default body size setting fails with 413 on every push. The apisix-helm-chart 2.16.0 rendersclient_max_body_size: 0by default, so a default Helm installation is affected out of the box.Setting an explicit non-zero value (e.g.
1g) restores correct behavior for chunked requests.Expected Behavior
client_max_body_size: 0should mean "unlimited" for chunked requests as well, consistent with theContent-Lengthcase and with nginx's documented behavior.Error Logs
Nothing is written to the error log. The access log shows the 413 being generated by APISIX itself with no upstream involved:
Response:
Steps to Reproduce
config.yaml(standalone mode, minimal):apisix.yaml(any upstream works; it is never reached for chunked requests):client_max_body_sizeto1gand restart: the chunked request now returns 502 (passes through) as expected.Notes:
nginx_config.http.client_max_body_sizeentirely reproduces the same 413, so the default configuration is affected too.Environment
apache/apisix:3.17.0-debian, also deployed via apisix-helm-chart 2.16.0)Server: APISIX/3.17.0)