Deleting NGINX Cache Puts Critical Unlink Errors in Error Log
Published: March 4, 2015 at 8:43:32 PM UTC
This article explains how to delete items from NGINX's cache without having your log files cluttered with error messages. While not generally a recommended approach, it may be useful in some edge cases.
The information in this post is based on FastCGI caching on NGINX 1.4.6 running on Ubuntu Server 14.04 x64. It may or may not be valid for other versions.
(Update 2025: In the time between I wrote the original post and now, a lot has changed. Servers are faster and cheaper, so I would in fact not recommend the approach described in this post where I try to micro-manage cache expiry just to save a few extra generations of dynamic content. I'll leave the content here for future reference and in case someone actually does need it for whatever reason. I have not confirmed that this still works for current versions of NGINX, though, but I'd think that it does).
After migrating several sites from Apache to NGINX I have grown very fond of its built-in caching capabilities, which works extremely well under most circumstances without much meddling from me.
However, for one of the sites, I really needed the ability to clear the cache (both fully and remove individual entries) myself. The free community edition of NGINX only supports time-based cache expiry (i.e. you can set it up to check if something has changed after an hour, a day, etc.). But what if there is no reliable way of determining ahead of time when a certain resource will change? For example, I have no idea if it will be an hour, a day or a year before I come back and edit something in this post – and why only cache for an hour if caching for a day would have been fine?
This is where the ability to clear the cache manually (or by having your web application notify NGINX that something should be purged) is needed. The people behind NGINX are clearly aware of the need for this as the feature is supported in the paid version of their product – but while they are certainly entitled to set up their licensing any way they want, the price is a bit steep for me when this function is the only paid feature I really need.
Fortunately, it turns out you can just delete files from the cache directory yourself and NGINX will pick up on this and fetch a new copy from your back-end without a hitch. However, if you do this without tweaking your configuration you are likely to see a whole bunch of messages similar to this one in your error log after a while:
It appears that these errors occur when NGINX itself tries to delete cache entries after the time specified by the inactive parameter of the fastcgi_cache_path directive. The default for this is only 10 minutes, but you can set it to whatever value you want. If you set it to, say, 10 years, it's probably unlikely that you haven't restarted the server in the meantime so the key index in memory would have been cleared in the meantime. If you do this, do you need to make sure that you clear the cache yourself, NGINX will no longer to do it for you.
I find it really strange that it is considered a critical error that a cache entry cannot be deleted because it doesn’t exist. The fact that its severity classification is so high means that it’s impossible to get rid of just by ignoring log entries below a certain threshold. As soon as a new copy is fetched from the back-end the entry will exist again, so this should be a warning at most, in my opinion.
Now, if the cache entry couldn’t be deleted because of problems with permissions or something third, that would be a critical error, because it might make NGINX continue serving cached content long after its expiry time, but the clean-up process doesn’t seem to make this distinction.