Serving application HTTP/5xx error pages via Varnish

cachehttpPROXYvarnish

I an working on running a few Rails applications through Varnish to provide better caching support which will hopefully be more flexible then the build in page-cache options in rails.

One issue I have stumbled upon is that when a HTTP/50x error is returned from the application server varnish does not serve up the custom error page (e.g. when the rails app raises an exception we render a custom error HTML template) – instead of seeing the 'nice' user friendly error page we see the following text:

Error 503 Service Unavailable

Service Unavailable

Guru Meditation:

XID: 828451354

Varnish cache server

Is there any way to possibly pass the fetched HTML from the backend server to the client? Is it as easy as implementing the sub_error VCL method and using a fetch or pass directive?

Thanks.

Best Answer

Well, I have an answer - and surprisingly the problem wasn't even that varnish wasn't passing on the HTTP/500 response content.

The HTTP/503 error was actually being thrown up when Varnish was timing out while connecting to the backend server, or waiting for bytes to be sent.

Basically, if the connection to the backend was successful, but the backend doesn't send the first byte without a certain timeout period, or there is a delay between sending bytes, Varnish will timeout and return a HTTP/503 error.

The solution is to update the timeout values (and of course, fix up the slow backend server) such as below (as detailed at: http://varnish-cache.org/wiki/VCL):

backend www {
   .host = "www.example.com";
   .port = "http";
   .connect_timeout = 1s;
   .first_byte_timeout = 5s;
   .between_bytes_timeout = 2s;
}