﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc	uname	nginx_version
1614	proxy cache 404 STALE forever	d.jarosch.syseleven.de@…		"Hello guys,

I'm having a hard time to understand if I'm having a bug in my configuration or if I hit a bug in NGINX.

My configuration so far:

{{{
proxy_cache_valid             200 15s;
proxy_cache_valid             301 15s;
proxy_cache_valid             404 15s;
proxy_cache                   stage_proxy-cache;
proxy_cache_lock              on;
proxy_cache_use_stale         updating error timeout http_404 http_500 http_502 http_503 http_504;
proxy_cache_background_update on;
proxy_cache_revalidate        on;
}}}

Our application, a Magnolia CMS, is defining the Cache-Control header via max-age and therfor controling how long an asset has to be kept in cache before it becomes STALE.

Now I'm experiencing a ""strange"" behavior which I don't understand. The behavior is as following:

- I'm curling for an object like a HTML 3 times:

{{{
→ curl -I https://invaliddomain-com.stage.invaliddomain.info/en/products/formwork/concrete-maturity-computer.html
HTTP/2 200
server: nginx
date: Mon, 20 Aug 2018 09:41:29 GMT
content-type: text/html;charset=UTF-8
content-length: 72937
x-magnolia-registration: Registered
access-control-allow-origin: http://tools.live.invaliddomain.info
access-control-allow-methods: GET, OPTIONS, HEAD
access-control-allow-headers: X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept
cache-control: max-age=60, public
expires: Mon, 20 Aug 2018 09:42:29 GMT
last-modified: Mon, 20 Aug 2018 09:37:28 GMT
x-upstream: 10.6.198.15:8080
content-security-policy: default-src 'self' http: https:;img-src http: https: data:;font-src http: https: data:;script-src 'unsafe-inline' 'unsafe-eval' 'self' http: https:;style-src 'unsafe-inline' http: https:; frame-ancestors http://*.stage.invaliddomain.info https://*.stage.invaliddomain.info http://*.live.invaliddomain.info https://*.live.invaliddomain.info
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
x-cache: MISS

→ curl -I https://invaliddomain-com.stage.invaliddomain.info/en/products/formwork/concrete-maturity-computer.html
HTTP/2 200
server: nginx
date: Mon, 20 Aug 2018 09:41:32 GMT
content-type: text/html;charset=UTF-8
content-length: 72937
x-magnolia-registration: Registered
access-control-allow-origin: http://tools.live.invaliddomain.info
access-control-allow-methods: GET, OPTIONS, HEAD
access-control-allow-headers: X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept
cache-control: max-age=60, public
expires: Mon, 20 Aug 2018 09:42:29 GMT
last-modified: Mon, 20 Aug 2018 09:37:28 GMT
content-security-policy: default-src 'self' http: https:;img-src http: https: data:;font-src http: https: data:;script-src 'unsafe-inline' 'unsafe-eval' 'self' http: https:;style-src 'unsafe-inline' http: https:; frame-ancestors http://*.stage.invaliddomain.info https://*.stage.invaliddomain.info http://*.live.invaliddomain.info https://*.live.invaliddomain.info
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
x-cache: HIT

... after more then 60 seconds (cache-control: max-age)

HTTP/1.1 200
Server: nginx
Date: Mon, 20 Aug 2018 09:45:07 GMT
Content-Type: text/html;charset=UTF-8
Content-Length: 72937
Connection: keep-alive
Keep-Alive: timeout=5
X-Magnolia-Registration: Registered
Access-Control-Allow-Origin: http://tools.live.invaliddomain.info
Access-Control-Allow-Methods: GET, OPTIONS, HEAD
Access-Control-Allow-Headers: X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept
Cache-Control: max-age=60, public
Expires: Mon, 20 Aug 2018 09:44:47 GMT
Last-Modified: Mon, 20 Aug 2018 09:37:28 GMT
Content-Security-Policy: default-src 'self' http: https:;img-src http: https: data:;font-src http: https: data:;script-src 'unsafe-inline' 'unsafe-eval' 'self' http: https:;style-src 'unsafe-inline' http: https:; frame-ancestors http://*.stage.invaliddomain.info https://*.stage.invaliddomain.info http://*.live.invaliddomain.info https://*.live.invaliddomain.info
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-CACHE: STALE
}}}

Since the object hasn't been in the cache yet, first I receive a MISS, with the second request within 60 seconds I receive a X-CACHE: HIT and after more then 60 seconds of not requesting the object I receive a STALE and with the next curl again a HIT. Fine for me, everything works as expected for existing objects.

- Now I'm doing this for a page which actually doesn't exists like following:

{{{
curl -I https://invaliddomain-com.stage.invaliddomain.info/en/testpage.html
HTTP/1.1 404
Server: nginx
Date: Mon, 20 Aug 2018 09:56:18 GMT
Content-Type: text/html;charset=UTF-8
Connection: keep-alive
Keep-Alive: timeout=5
X-Magnolia-Registration: Registered
Access-Control-Allow-Origin: http://tools.live.invaliddomain.info
Access-Control-Allow-Methods: GET, OPTIONS, HEAD
Access-Control-Allow-Headers: X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept
Cache-Control: max-age=60
Expires: Mon, 20 Aug 2018 09:57:05 GMT
}}}

First thing I realize is that there is no X-CACHE status comming back, but according to the NGINX access log I've ""hit"" somthing:

{{{
[20/Aug/2018:11:58:53 +0200] Cache: MISS 10.6.198.15:8080 0.573 404 458 37.44.6.6 invaliddomain-com.stage.invaliddomain.info /en/testpage.html
[20/Aug/2018:11:58:54 +0200] Cache: HIT - - 404 458 37.44.6.6 invaliddomain-com.stage.invaliddomain.info /en/testpage.html
}}}

According to the Cache-Control header I should receive a STALE after 60 seconds and I do:

{{{
[20/Aug/2018:11:59:55 +0200] Cache: STALE - - 404 458 37.44.6.6 invaliddomain-com.stage.invaliddomain.info /en/testpage.html
}}}

But I'm not leaving this status anymore until I purge the NGINX proxy cache:

{{{
...
[20/Aug/2018:12:00:13 +0200] Cache: STALE - - 404 458 37.44.6.6 invaliddomain-com.stage.invaliddomain.info /en/testpage.html
[20/Aug/2018:12:00:14 +0200] Cache: STALE - - 404 458 37.44.6.6 invaliddomain-com.stage.invaliddomain.info /en/testpage.html
[20/Aug/2018:12:00:15 +0200] Cache: STALE - - 404 458 37.44.6.6 invaliddomain-com.stage.invaliddomain.info /en/testpage.html
[20/Aug/2018:12:00:16 +0200] Cache: STALE - - 404 458 37.44.6.6 invaliddomain-com.stage.invaliddomain.info /en/testpage.html
...
}}}

Now I'm having a tricky situation. Let's say I'm removing an object from my backend by disabling it (404) for remake or whatever (new CSS etc.). The object is not available and I'm receiving a STALE 404 after while from cache. After finished remake of my object I'm enabling it again to be available, but I'm still receiving an 404 STALE object from cache, and therefor my new object won't be available until I purge the proxy cache.

My questions are:

- Do I have a configuration error?
- Do I misunderstand the proxy cache concept?
- Is this behavior expected?
- Are there any solutions for my problem?"	defect	closed	minor		other	1.15.x	duplicate	proxy_cache stale proxy_cache_valid proxy_cache_use_stale		Linux lb.info 2.6.32-042stab127.2 #1 SMP Thu Jan 4 16:41:44 MSK 2018 x86_64 x86_64 x86_64 GNU/Linux	"nginx version: nginx/1.15.2
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
built with OpenSSL 1.0.2g  1 Mar 2016
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/nginx.pid --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 -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie'"
