Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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

share|improve this question
    
Could be done with some inline C, see: mohanjith.net/blog/2009/08/… – 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
up vote 12 down vote accepted

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 -->
        "};
    }
}
share|improve this answer

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.

share|improve this answer
    
Please 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 serverfault.com/a/665917/102757 and serverfault.com/a/716767/102757 – lucaferrario Jun 7 at 14:39

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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