Well first of all i am using the Porto theme and using the SW mega menu. I'm currently running magento 2.0.4.

It seems that when i turn on varnish on my webhost and configure everything that it is working except it is not showing my top navigation menu. For some reason i think the mega menu vs Varnish causes this.

My Current VCL file :

# The minimal Varnish version is 3.0.5

backend default {
    .host = "";
    .port = "10175"; }

acl purge {
    ""; }

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;

    if (req.request == "PURGE") {
        if (client.ip !~ purge) {
            error 405 "Method not allowed";
        if (!req.http.X-Magento-Tags-Pattern) {
            error 400 "X-Magento-Tags-Pattern header required";
        ban("obj.http.X-Magento-Tags ~ " + req.http.X-Magento-Tags-Pattern);
        error 200 "Purged";

    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);

    # We only deal with GET and HEAD by default
    if (req.request != "GET" && req.request != "HEAD") {
        return (pass);

    # Bypass shopping cart and checkout requests
    if (req.url ~ "/checkout") {
        return (pass);

    # normalize url in case of leading HTTP scheme and domain
    set req.url = regsub(req.url, "^http[s]?://", "");

    # collect all cookies

    # static files are always cacheable. remove SSL flag and cookie
    if (req.url ~ "^/(pub/)?(media|static)/.*\.(ico|css|js|jpg|jpeg|png|gif|tiff|bmp|gz|tgz|bz2|tbz|mp3|ogg|svg|swf|woff|woff2|eot|ttf|otf)$") {
        unset req.http.Https;
        unset req.http.Cookie;

    set req.grace = 1m;

    return (lookup); }

sub vcl_hash {
    if (req.http.cookie ~ "X-Magento-Vary=") {
        hash_data(regsub(req.http.cookie, "^.*?X-Magento-Vary=([^;]+);*.*$", "\1"));

sub vcl_fetch {
    if (beresp.http.content-type ~ "text") {
        set beresp.do_esi = true;

    if (req.url ~ "\.js$" || beresp.http.content-type ~ "text") {
        set beresp.do_gzip = true;

    # cache only successfully responses and 404s
    if (beresp.status != 200 && beresp.status != 404) {
        set beresp.ttl = 0s;
        return (hit_for_pass);
    } elsif (beresp.http.Cache-Control ~ "private") {
        return (hit_for_pass);

    if (beresp.http.X-Magento-Debug) {
        set beresp.http.X-Magento-Cache-Control = beresp.http.Cache-Control;

    # validate if we need to cache it and prevent from setting cookie
    # images, css and js are cacheable by default so we have to remove cookie also
    if (beresp.ttl > 0s && (req.request == "GET" || req.request == "HEAD")) {
        unset beresp.http.set-cookie;
            if (req.url !~ "\.(ico|css|js|jpg|jpeg|png|gif|tiff|bmp|mp3|ogg|svg|swf|woff|woff2|eot|ttf|otf)(\?|$)") {
            set beresp.http.Pragma = "no-cache";
            set beresp.http.Expires = "-1";
            set beresp.http.Cache-Control = "no-store, no-cache, must-revalidate, max-age=0";
            set beresp.grace = 1m;
    } }

sub vcl_deliver {
    if (resp.http.X-Magento-Debug) {
        if (obj.hits > 0) {
            set resp.http.X-Magento-Cache-Debug = "HIT";
        } else {
            set resp.http.X-Magento-Cache-Debug = "MISS";
    } else {
        unset resp.http.Age;

    unset resp.http.X-Magento-Debug;
    unset resp.http.X-Magento-Tags;
    unset resp.http.X-Powered-By;
    unset resp.http.Server;
    unset resp.http.X-Varnish;
    unset resp.http.Via;
    unset resp.http.Link; }

Does anyone has an idea how i can adjust this so my menu appears while varnish is turned on?

Everything works when Varnish is not on in the backend of magento.


7 Answers 7


I had the same issue, I found a solution for this.

I just removed the ttl attribute from /vendor/magento/module-theme/view/frontend/layout/default.xml and the menu bar appeared again.

  • thanks great answer! solved issue on prod..but any technical explanation for this?
    – huzefam
    Commented Aug 9, 2017 at 19:01
  • how to i override in custom theme?
    – huzefam
    Commented Aug 9, 2017 at 19:07
  • 3
    This does not solve the problem. It just removes the block from the esi:include. Is there a way to let the block in there, but still make it work properly?
    – Marius
    Commented Sep 21, 2017 at 13:53
  • Why is this happening in the first place? Any way to leave the TTL in there and make it work?
    – Erfan
    Commented Jan 29, 2018 at 17:23
  • @Amit Naraniwala i am facing same issue magento.stackexchange.com/questions/229527/… is there any problem if i remove ttl attribute? Commented Sep 26, 2018 at 5:58

The solution is to remove the ttl attribute from the default.xml file in a Magento 2 theme:

  1. Edit default.xml in Your Custom Theme: In your custom theme under app/design/frontend/<Vendor>/<theme>/Magento_Theme/layout, edit the default.xml file with the following code:

    <referenceBlock name="catalog.topnav">
        <action method="unsetData">
            <argument name="key" xsi:type="string">ttl</argument>

    This code effectively removes the ttl attribute from the catalog.topnav block.

  2. Clear Cache: After updating the file, clear the Magento cache by running:

    php bin/magento cache:clean
  3. Verify the Cache Behavior: Check the "X-Magento-Cache-Debug" header in your browser to ensure it shows a "MISS" value, indicating that the cache for this block is not being stored.

  4. Configure Cache Cleanup for Varnish (If Necessary): If you encounter issues with caching, especially when using Varnish, refer to Adobe's guide on configuring cache cleanup for Varnish in Magento 2: Configure and use Varnish.


Since I'm not using HTTPS, I just put in http://www.versdivers.be in my secure base URL and this fixed the problem.

If you are using HTTPS then you will need to do what Khoa posted:

http://github.com/magento/magento2/issues/3897 – Khoa TruongDinh yesterday


I removed all ttl attributes in app\code\Magestore\Megamenu\view\frontend\layout\default.xml and menu showed up


i found a solution for that problem.

just add this lines into your vcl:

# Bypass esi requests
if (req.url ~ "/page_cache/block/esi/blocks/") {
    return (pass);

this will prevent varnish from trying reading the menu from the varnish cache. It will always fetched from the backend (magento)

This is fast enough so you get no time increases.


Your best bet is to override the menu in your custom theme in case future Magento upgrades overwrite your changes in the vendor folder. This will restore the menu when using Varnish cache.


<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    <referenceContainer name="page.top">
        <block class="Magento\Framework\View\Element\Template" name="navigation.sections" before="-"
                <argument name="group_name" xsi:type="string">navigation-sections</argument>
                <argument name="group_css" xsi:type="string">nav-sections</argument>
            <block class="Magento\Framework\View\Element\Template" name="store.menu" group="navigation-sections"
                    <argument name="title" translate="true" xsi:type="string">Menu</argument>
                <block class="Magento\Theme\Block\Html\Topmenu" name="catalog.topnav"
                       template="Magento_Theme::html/topmenu.phtml" before="-"/>

Y como proceder si uso fastly, el atributo ttl no existe con fastrly en el archivo layout default.cml / And how to proceed if I use fastly, the ttl attribute does not exist with fastrly in the layout default.cml file

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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