Varnish delivering wrong content

varnish

I installed varnish, and face what I consider as a major issue :

Sometimes several different URLs, show the same cached content.

And if you go on a page that show the content from a wrong page and that you force refresh (CTRL + F5), then you have the right content from the backend directly.

For example, instead of showing :

Intended content

Sometimes it caches :

(see the log in the picture)

This happens even with a default VCL file.

Why is this happening?

Regards,

Here is my varnish configuration file :

backend default {
.host = "127.0.0.1";
.port = "8080"; # We will then configure apache to listen to port 8080
}


sub vcl_recv {
if (req.restarts == 0) {
if (req.http.x-forwarded-for) {
set req.http.X-Forwarded-For =
req.http.X-Forwarded-For + ", " + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
}

# Don't cache till session end
if (req.http.cookie ~ "SIWOID") {
return(pass);
}

if (req.request != "GET" &&
req.request != "HEAD" &&
req.request != "PUT" &&
req.request != "POST" &&
req.request != "TRACE" &&
req.request != "OPTIONS" &&
req.request != "DELETE") {
/* Non-RFC2616 or CONNECT which is weird. */
return (pipe);
}
if (req.request != "GET" && req.request != "HEAD") {
/* We only deal with GET and HEAD by default */
return (pass);
}
if (req.http.Authorization) {
/* Not cacheable by default */
return (pass);
}
# parse accept encoding rulesets to normalize
if (req.http.Accept-Encoding) {
if (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} elsif (req.http.Accept-Encoding ~ "deflate") {
set req.http.Accept-Encoding = "deflate";
} else {
# unkown algorithm
remove req.http.Accept-Encoding;
}
}

# Rules for static files
if (req.url ~ "\.(jpeg|jpg|png|gif|ico|swf|js|css|gz|rar|txt|bzip|pdf)(\?.*|)$") {
set req.http.staticmarker = "1";
unset req.http.Cookie;

return (lookup);
}

# Remove cookie
unset req.http.Cookie;
set req.http.magicmarker = "1"; #Instruct varnish to remove cache headers received from backend
return(lookup);
}

sub vcl_pipe {
# Note that only the first request to the backend will have
# X-Forwarded-For set.  If you use X-Forwarded-For and want to
# have it set for all requests, make sure to have:
# set bereq.http.connection = "close";
# here.  It is not set by default as it might break some broken web
# applications, like IIS with NTLM authentication.
return (pipe);
}

sub vcl_pass {
return (pass);
}

sub vcl_hash {
hash_data(req.url);
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}

return (hash);
}

sub vcl_hit {
# force-refresh will update the cache
# http://www.varnish-cache.org/trac/wiki/VCLExampleEnableForceRefresh
if (req.http.pragma ~ "no-cache" || req.http.Cache-Control ~ "no-cache"){
# Ignore requests via proxy caches, IE users and badly behaved crawlers
# like msnbot that send no-cache with every request.
if (! (req.http.Via || req.http.User-AgeAgent ~ "bot|MSIE")) {
set req.http.X-Cacheable = "Rechargÿ77777751";
set obj.ttl = 0s;
return (restart);
}
}

if (obj.ttl <= 0s) {
set req.http.X-Cacheable = "Expirÿ77777751";
return (pass);
}
return (deliver);
}

sub vcl_miss {
return (fetch);
}

sub vcl_fetch {


set req.grace = 30s;

#    if (beresp.ttl <= 0s ||
#        beresp.http.Set-Cookie ||
#        beresp.http.Vary == "*") {
#                /*
#                 * Mark as "Hit-For-Pass" for the next 2 minutes
#                 */
#                set beresp.ttl = 120 s;
#                return (hit_for_pass);
#    }
#    return (deliver);

# Current response should not be cached
if(beresp.http.Set-Cookie ~ "SIWOID") {
return (deliver);
}

if (beresp.http.location ||
beresp.ttl <= 0s ||
beresp.http.Cache-Control ~ "(private|no-cache|no-store)" ||
beresp.http.Authorization && !beresp.http.Cache-Control ~ "public" ||
beresp.http.cache-control ~ "no-cache") {
set beresp.ttl = 0s;
#       set beresp.http.Pragma = "no-cache";
return(deliver);
}



# Flag set when we want to delete cache headers received from backend
if (req.http.magicmarker){
unset beresp.http.magicmarker;
unset beresp.http.Cache-Control;
unset beresp.http.Expires;
unset beresp.http.Pragma;
unset beresp.http.Cache;
unset beresp.http.Server;
unset beresp.http.Set-Cookie;
unset beresp.http.Age;

# default ttl for pages
set beresp.ttl = 1d;
}
if (req.http.staticmarker) {
set beresp.ttl = 30d; # static file cache expires in 30 days
unset beresp.http.staticmarker;
unset beresp.http.ETag; # Removes Etag in case we have multiple frontends
}

}

sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT ("+obj.hits+")";
} else {
set resp.http.X-Cache = "MISS";
}
#       set resp.http.X-Cache-Hash = obj.http.hash;
return (deliver);
}

sub vcl_error {
set obj.http.Content-Type = "text/html; charset=utf-8";
set obj.http.Retry-After = "5";
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>
<hr>
<p>Varnish cache server</p>
</body>
</html>
"};
return (deliver);
}

sub vcl_init {
return (ok);
}

sub vcl_fini {
return (ok);
}

In /etc/default/varnish i have :

DAEMON_OPTS="-a :80 \
         -T localhost:6082 \
         -f /etc/varnish/magento.vcl \
         -S /etc/varnish/secret \
         -p send_timeout=6000 \
         -s malloc,12G"

Best Answer

I had a similar problem, adding this to my vcl_recv fixed it:

vcl_recv {
    ...
# Add one of this per vhost, you may want to try set req.http.host = req.http.host; although I haven't tested that
if (req.http.host == "example1.com") {
    set req.http.host = "example1.com";
}

if (req.http.host == "example2.com") {
    set req.http.host = "example2.com";
}
    ...
return(lookup);
}

It doesn't make too much sense to me and I saw it on a online VCL, but completely fixed the issue when I was facing it on my server.

Related Topic