15

How can I tell Varnish to show a custom html error page instead of the default "Guru Meditation" message?

13

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 -->
        "};
    }
}
  • 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
18

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.