Home About Blog

How do I fix HTTP 416 responses from Varnish for video elements?

I have Varnish 4.0.3 configured for my site and I have a page with a <video> element with a URL for an mp4 file but the response comes back as HTTP 416 Requested Range Not Satisfiable.

How can I fix this and also ensure my video is cached for best performance?

The 416 error response looks to be an issue with how Varnish 4.0.x handles requests with a Range header that has an open ended range, e.g. bytes=0- when the object isn’t in cache. This is because the cache miss results in a backend fetch to the origin, but before the asset is fully downloaded, Varnish does not know it’s length and cannot compare the length against the request Range header.

See description from a Varnish dev: https://www.varnish-cache.org/lists/pipermail/varnish-dev/2015-October/008557.html

To fix it in Varnish 4.0.x you will need to accommodate for the cache miss scenario by removing the Range header from the request. This can be performed in vcl_miss see below:

sub vcl_miss { 
    if (req.url ~ "\.(mp4)(?=\?|&|$)" && req.http.Range ~ "bytes\=0\-$") {
       unset req.http.Range;
    }
}

To configure Varnish to cache the response you can set the following in vcl_recv

if (req.url ~ "\.(mp4)(?=\?|&|$)") {
    unset req.http.Cookie;
    return (hash);
}

and this in vcl_backend_response

if (bereq.url ~ "\.(mp4)(?=\?|&|$)") {
    unset beresp.http.set-cookie;
    set beresp.do_stream = true; # optional setting to allow streaming before response is fully complete from origin
    set beresp.ttl = 1d; # optional manual setting of TTL
}
1 Like