# Http 500 errors are not cached but go to the backend

**URL:** <https://www.ruby-forum.com/t/http-500-errors-are-not-cached-but-go-to-the-backend/229336>\
**Category:** NGINX\
**Created:** [January 4, 2013, 2:39pm UTC](https://www.ruby-forum.com/t/http-500-errors-are-not-cached-but-go-to-the-backend/229336 "2013-01-04T14:39:13Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![brama](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/aca169/32.png) [@brama](https://www.ruby-forum.com/u/brama)\
**Post date:** [January 4, 2013, 2:39pm UTC](https://www.ruby-forum.com/t/http-500-errors-are-not-cached-but-go-to-the-backend/229336/1 "2013-01-04T14:39:13Z")

</div>

Hi,

I’ve set up nginx (tested with 1.2.6 and 1.3.10) to cache all requests  
to  
our fastcgi backends. If a cache entry expires, stale entries wil be  
served  
while nginx is updating the cache. I’m using the fastcgi\_cache\_lock  
feature  
to make sure only 1 request will be sent to the backend to update the  
cache.

This works fine for everything but http 500 errors. If the backend  
produces  
a http 500 result, it will initially be cached for the  
fastcgi\_cache\_valid  
500 time (1 minute in my example), but when that expires, ALL requests  
for  
that document will go to the backend, instead of coming out of the  
cache.  
Also, the cache entry is never updated anymore, until it is removed from  
the  
cache altogether after 10 minutes (the value of ‘inactive’ in  
fastcgi\_cache\_path).

My cache config:

# in http context

fastcgi\_cache\_path /var/nginx/cache/content levels=1:2  
keys\_zone=content:24m  
inactive=10m max\_size=512M;

# in location context:

fastcgi\_cache content;

# cache entire url, but only sig&exp query string parameters

fastcgi\_cache\_key $scheme|$host|$uri?sig=$arg\_sig&exp=$arg\_exp;

# Ignore caching headers from the response so that clients will not

cache

# the results; nginx, however, will cache everything

fastcgi\_ignore\_headers Expires Cache-Control;

fastcgi\_cache\_valid 500 1m;  
fastcgi\_cache\_valid any 1m;

# start caching at the first request

fastcgi\_cache\_min\_uses 1;

# serve stale cache entries if the fastcgi backend acts up, and also

while

# a new entry is being generated

# XXX for some reason, if http\_500 is included here, EACH hit will go to

the

# backend as soon as the initial cache entry becomes stale. Bug?

fastcgi\_cache\_use\_stale error timeout invalid\_header updating http\_500;

# only allow 1 backend request to generate a cache entry at any time;

all  
other

# connections wait for it.

fastcgi\_cache\_lock on;

# wait max 20s for a cache entry to be generated

fastcgi\_cache\_lock\_timeout 20s;

As an example, I made the fastcgi backend log each & every request it  
receives. I am hammering the server with ab -c100 -n500000 and this is  
what  
the backend logs (each request produces a http 500):

# I start hammering here with 100 concurrent requests. Only 1 request is

received at the backend:  
2013-01-03 22:00:33 content\_server.dynamic.main:344 INFO CONTENT SERVER  
BACKEND REQUEST FOR: [http://myserver.localhost/dynamic/http\_500.js](http://myserver.localhost/dynamic/http_500.js)

# Now, it’s quiet for exactly 1 minute, and then ALL requests go to the

backend:  
2013-01-03 22:01:34 content\_server.dynamic.main:344 INFO CONTENT SERVER  
BACKEND REQUEST FOR: [http://myserver.localhost/dynamic/http\_500.js](http://myserver.localhost/dynamic/http_500.js)  
2013-01-03 22:01:34 content\_server.dynamic.main:344 INFO CONTENT SERVER  
BACKEND REQUEST FOR: [http://myserver.localhost/dynamic/http\_500.js](http://myserver.localhost/dynamic/http_500.js)  
2013-01-03 22:01:34 content\_server.dynamic.main:344 INFO CONTENT SERVER  
BACKEND REQUEST FOR: [http://myserver.localhost/dynamic/http\_500.js](http://myserver.localhost/dynamic/http_500.js)  
2013-01-03 22:01:34 content\_server.dynamic.main:344 INFO CONTENT SERVER  
BACKEND REQUEST FOR: [http://myserver.localhost/dynamic/http\_500.js](http://myserver.localhost/dynamic/http_500.js)  
2013-01-03 22:01:34 content\_server.dynamic.main:344 INFO CONTENT SERVER  
BACKEND REQUEST FOR: [http://myserver.localhost/dynamic/http\_500.js](http://myserver.localhost/dynamic/http_500.js)  
2013-01-03 22:01:34 content\_server.dynamic.main:344 INFO CONTENT SERVER  
BACKEND REQUEST FOR: [http://myserver.localhost/dynamic/http\_500.js](http://myserver.localhost/dynamic/http_500.js)  
2013-01-03 22:01:34 content\_server.dynamic.main:344 INFO CONTENT SERVER  
BACKEND REQUEST FOR: [http://myserver.localhost/dynamic/http\_500.js](http://myserver.localhost/dynamic/http_500.js)  
2013-01-03 22:01:34 content\_server.dynamic.main:344 INFO CONTENT SERVER  
BACKEND REQUEST FOR: [http://myserver.localhost/dynamic/http\_500.js](http://myserver.localhost/dynamic/http_500.js)

I’ve logged the cache status results in the logfile, and this is the  
contents of the access log at the time the cache entry expires at  
22:01:34:

“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “STALE”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “STALE”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”

“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “STALE”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:01:34 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”

If I remove http\_500 from fastcgi\_cache\_use\_stale, THEN only 1 entry  
will go  
to the backend if it expires, as desired. The access log then looks like  
this as soon as the cache entry expires:

“192.168.63.171” myserver.localhost - [03/Jan/2013:22:14:53 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:14:53 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:14:53 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:14:53 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:14:53 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:14:54 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “UPDATING”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:14:54 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:14:54 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “EXPIRED”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:14:54 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:14:54 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:14:54 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:14:54 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:14:54 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”  
“192.168.63.171” myserver.localhost - [03/Jan/2013:22:14:54 +0000] “GET  
/dynamic/http\_500.js HTTP/1.0” 500 31 “-” “ApacheBench/2.3” “HIT”

This seems counter-intuitive. If the http 500 document expires, nginx  
should  
serve the stale cache entry until it has updated the cache entry.  
However,  
with http\_500 included in fastcgi\_cache\_use\_stale, it never appears to  
update the cache entry at all. Bug?

Posted at Nginx Forum:

> **[http 500 errors are not cached but go to the backend](https://forum.nginx.org/read.php?2,234691,234691#msg-234691)**
>
> Hi, I've set up nginx (tested with 1.2.6 and 1.3.10) to cache all requests to our fastcgi backends. If a cache entry expires, stale entries wil be served while nginx is updating the cache. I'm using the fastcgi\_cache\_lock feature to make sure only 1...

---

<div class="post-metadata">

**Author:** ![brama](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/aca169/32.png) [@brama](https://www.ruby-forum.com/u/brama)\
**Post date:** [January 4, 2013, 11:31pm UTC](https://www.ruby-forum.com/t/http-500-errors-are-not-cached-but-go-to-the-backend/229336/2 "2013-01-04T23:31:24Z")

</div>

Hello!

On Fri, Jan 04, 2013 at 08:38:53AM -0500, brama wrote:

> I’ve set up nginx (tested with 1.2.6 and 1.3.10) to cache all requests to  
> our fastcgi backends. If a cache entry expires, stale entries wil be served  
> while nginx is updating the cache. I’m using the fastcgi\_cache\_lock feature  
> to make sure only 1 request will be sent to the backend to update the  
> cache.

Just a side note: the fastcgi\_cache\_lock directive doesn’t affect  
update of the cache, it only affects adding new items to the  
cache. To handle cache updating the “fastcgi\_cache\_use\_stale  
updating” should be used (it’s actually already in your config).

[…]

> This seems counter-intuitive. If the http 500 document expires, nginx should  
> serve the stale cache entry until it has updated the cache entry. However,  
> with http\_500 included in fastcgi\_cache\_use\_stale, it never appears to  
> update the cache entry at all. Bug?

The

fastcgi\_cache\_use\_stale http\_500;

in your config instructs nginx to don’t cache 500 response but  
return stale cached content instead. As soon as original cached  
resource expires - nginx starts to ask backend about new response,  
but since 500 is returned it returns stale response to clients  
instead.

In your case the behaviour looks a bit confusing as “original  
cached resource” above is the same 500 response (cached as  
fastcgi\_cache\_use\_stale don’t affect initial content caching), but  
the behaviour is as expected with your configuration - when you  
ask nginx to cache 500 responses and to don’t use 500 responses  
for cache update at the same time.

–  
Maxim D.

> **[F5 NGINX: Built for cloud-native apps. Ready for AI traffic.](https://www.f5.com/products/nginx)**
>
> Deliver modern applications with NGINX. Explore high-performance load balancing, API gateways, and web server solutions trusted by top global enterprises.

---

<div class="post-metadata">

**Author:** ![brama](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/aca169/32.png) [@brama](https://www.ruby-forum.com/u/brama)\
**Post date:** [January 8, 2013, 11:19am UTC](https://www.ruby-forum.com/t/http-500-errors-are-not-cached-but-go-to-the-backend/229336/3 "2013-01-08T11:19:53Z")

</div>

Hi Maxim,

> Just a side note: the fastcgi\_cache\_lock directive doesn’t affect  
> update of the cache, it only affects adding new items to the  
> cache. To handle cache updating the “fastcgi\_cache\_use\_stale  
> updating” should be used (it’s actually already in your config).

Ok, that’s good to know.

> In your case the behaviour looks a bit confusing as “original  
> cached resource” above is the same 500 response (cached as  
> fastcgi\_cache\_use\_stale don’t affect initial content caching), but  
> the behaviour is as expected with your configuration - when you  
> ask nginx to cache 500 responses and to don’t use 500 responses  
> for cache update at the same time.

Ok, got it. That was indeed confusing. Thanks for your explanation.

Bram

Posted at Nginx Forum:  
[http://forum.nginx.org/read.php?2,234691,234782#msg-234782](http://forum.nginx.org/read.php?2,234691,234782#msg-234782)
