Opened 12 months ago

Closed 12 months ago

Last modified 12 months ago

#2459 closed defect (invalid)

X-Accel-Redirect'ed response contains both upstreams Cache-Control headers, not only the last one

Reported by: Dmitrii Titarenko Owned by:
Priority: minor Milestone:
Component: nginx-core Version: 1.23.x
Keywords: Cc:
uname -a: Linux usr-VirtualBox 5.15.0-46-generic #49-Ubuntu SMP Thu Aug 4 18:03:25 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.23.3
built by gcc 11.2.0 (Ubuntu 11.2.0-19ubuntu1)
built with OpenSSL 3.0.2 15 Mar 2022
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/ --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-g -O2 -ffile-prefix-map=/data/builder/debuild/nginx-1.23.3/debian/debuild-base/nginx-1.23.3=. -flto=auto -ffat-lto-objects -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' --with-ld-opt='-Wl,-Bsymbolic-functions -flto=auto -ffat-lto-objects -flto=auto -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie'



server {
    listen       80;
    server_name  localhost;

    location / {

    location /int/ {

Run 2 upstreams, the first one is for an external location with X-Accel-Redirect:

while true; do printf 'HTTP/1.1 200 OK\r\nX-Accel-Redirect:/int/\r\nCache-Control:no-cache,no-store\r\nContent-Length:0\r\n\r\n'; done | nc -vklp 8000

And the second one is for an internal location:

while true; do printf 'HTTP/1.1 200 OK\r\nContent-Type:text/plain\r\nCache-Control:private,max-age=123\r\nContent-Length:5\r\n\r\nHello'; done | nc -vklp 8888

Run curl to the external location:

$ curl -v
*   Trying
* Connected to ( port 80 (#0)
> GET / HTTP/1.1
> Host:
> User-Agent: curl/7.81.0
> Accept: */*
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx/1.23.3
< Date: Thu, 23 Feb 2023 18:09:40 GMT
< Content-Type: text/plain
< Content-Length: 5
< Connection: keep-alive
< Cache-Control: no-cache,no-store          <--- (!)
< Cache-Control: private,max-age=123        <--- (!)
* Connection #0 to host localhost left intact

Both Cache-Control headers are present in the response. Expected: only the last one.

Some web frameworks add 'Cache-Control:private' by default (sometimes without provided way to change this behaviour). In that case response contains complete duplicates.

Change History (2)

comment:1 by Maxim Dounin, 12 months ago

Resolution: invalid
Status: newclosed

The X-Accel-Redirect header redirects nginx to a different URI, with the following headers are copied to the response: "Content-Type", "Set-Cookie", "Content-Disposition", "Cache-Control", "Expires", and "Accept-Ranges". This behaviour makes it possible to effectively return static files from disk while controlling the headers being returned with the file from the script which does redirections. If you don't want nginx to use the headers in the final response, avoid returning them along with the X-Accel-Redirect redirection.

comment:2 by Dmitrii Titarenko, 12 months ago

Ok, thanks. In my opinion, it is not super obvious behavior (maybe it could be described in the documentation? couldn't find such details), because it seems X-Accel-Redirect is not only for static files. Also the web framework may not support added-by-default header removal from response (this is stupid of course, but that's how old behaves, can only change header value on smth different or totally disable default adding behavior). Surely can come up with some kind of crutch. As I see it, ideally, to have some separate headers or magic prefix to forward headers in response, smth like X-Accel-Add-Cache-Control.

Last edited 12 months ago by Dmitrii Titarenko (previous) (diff)
Note: See TracTickets for help on using tickets.