2

I have nginx with backend nodejs/php-fpm backend how tell the nginx dont cache the response 5xx or 4xx even it's matched for cache parameters.

PHP/Node.js header response long cache time via http headers:

HTTP/1.1 500 Internal Server Error
Date: Thu, 09 Mar 2017 09:41:03 GMT
Pragma: public
Expires: Thu, 09 Mar 2018 09:41:03 GMT
Cache-Control: public, max-age=31536000
X-Accel-Expires: Thu, 09 Mar 2018 09:41:03 GMT

Response will cache even the status code is 500 how to prevent it?

nginx config:

  location / {
    proxy_cache_methods GET;
    proxy_cache_key $request_uri;
    proxy_cache cache;
    proxy_cache_valid 200 1h;
    proxy_cache_use_stale error timeout invalid_header updating;
    proxy_cache_bypass 0;
    proxy_no_cache 0;
    proxy_redirect off;
    proxy_pass http://node-app;
  }
sweb
  • 451
  • 1
  • 9
  • 27

2 Answers2

3

Well, it is strange enough, that your backend sends Cache-Control header for 4xx/5xx errors.

Nginx can be configured via proxy_cache_valid directive OR it can take cache-settings from Cache-Control/Expires/... headers. This options can be mixed, but not in your situation.

So, you have two options:

  1. Ask your developers not to send Cache-Control headers when it is not needed (i.e. for 4xx/5xx codes)
  2. Configure Nginx to disable processing of Expires/Cache-Control backend response headers with proxy_ignore_headers.
Frodox
  • 31
  • 3
1

By default, nginx will honor the Cache-Control received from the backend for its own proxy cache, see e.g. https://forum.nginx.org/read.php?2,268813,268814

So it seems that the best solution would be to change your backend to stop emitting these headers in case of errors.

If you really want to override those 500s in nginx, maybe use proxy_cache_valid with 500 and 0 as the parameters? It definitely means second-guessing the backend, so it could have unintended consequences either way.

Josip Rodin
  • 1,575
  • 11
  • 17
  • According to http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_valid, "[parameters in the response header] have higher priority than setting of caching time using the directive" – ggradnig Feb 10 '22 at 16:09
  • @ggradnig exactly, it's logical that the backend should not really be second-guessed, I guess they updated the documentation to explicate the inability to do so using this directive since I hinted at that four years ago. – Josip Rodin Feb 10 '22 at 20:13