How can I tell Varnish to show a custom html error page instead of the default "Guru Meditation" message?
-
Could be done with some inline C, see: http://mohanjith.net/blog/2009/08/using-custom-error-pages-in-varnish.html – 3molo Mar 16 '11 at 12:35
-
Thanks, why don't you make that comment a suggested answer? – Christian Davén Mar 16 '11 at 12:57
2 Answers
Note that the above answers are for Varnish 3. As the question does not not specify version information, it seems an appropriate time to include the answer for Version 4 also as it has changed.
Hopefully this will save people from reading the above answers and putting vcl_error into their V4 VCL :)
Builtin VCL for Varnish 4.0
sub vcl_synth {
set resp.http.Content-Type = "text/html; charset=utf-8";
set resp.http.Retry-After = "5";
synthetic( {"<!DOCTYPE html>
<html>
<head>
<title>"} + resp.status + " " + resp.reason + {"</title>
</head>
<body>
<h1>Error "} + resp.status + " " + resp.reason + {"</h1>
<p>"} + resp.reason + {"</p>
<h3>Guru Meditation:</h3>
<p>XID: "} + req.xid + {"</p>
<hr>
<p>Varnish cache server</p>
</body>
</html>
"} );
return (deliver);
}
Note also that if you want to throw an error from within your VCL, you no longer use the 'error' function, instead you would do:
return (synth(405));
Also, 413, 417 and 503 errors from the backend are autmatically routed through this funtion.
- 333
- 3
- 6
-
2Please note that this will not capture "backend fetch errors". To capture them, you must also create a `sub vcl_backend_error`, as you can see in http://serverfault.com/a/665917/102757 and http://serverfault.com/a/716767/102757 – lucaferrario Jun 07 '16 at 14:39
The Varnish FAQ suggests using vcl_error for this (and it's how I've done it):
This is the default VCL for the error page:
sub vcl_error {
set obj.http.Content-Type = "text/html; charset=utf-8";
synthetic {"
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>"} obj.status " " obj.response {"</title>
</head>
<body>
<h1>Error "} obj.status " " obj.response {"</h1>
<p>"} obj.response {"</p>
<h3>Guru Meditation:</h3>
<p>XID: "} req.xid {"</p>
<address><a href="http://www.varnish-cache.org/">Varnish</a></address>
</body>
</html>
"};
return(deliver);
}
if you want a custom version, simply override the function in your config and replace the markup in the synthetic
statement.
If you want to have different markup for different error codes you can do that fairly easily too:
sub vcl_error {
set obj.http.Content-Type = "text/html; charset=utf-8";
if (obj.status == 404) {
synthetic {"
<!-- Markup for the 404 page goes here -->
"};
} else if (obj.status == 500) {
synthetic {"
<!-- Markup for the 500 page goes here -->
"};
} else {
synthetic {"
<!-- Markup for a generic error page goes here -->
"};
}
}
- 391
- 1
- 4
- 13
- 938
- 1
- 7
- 17
-
this does not work in VCL 4.0 - if you use vcl 4.0 then see answer below – Philipp Apr 13 '18 at 17:11