Phantomjs: Phantomjs 2.0- [CRITICAL] QNetworkReplyImpl: backend error: caching was enabled after some bytes had been written

Created on 20 Apr 2015  路  27Comments  路  Source: ariya/phantomjs

I am using Phantomjs 2.0 as a screenshot service and about 5-10% of the time I run it to generate an image I get the following error:
[Error: Command failed: 2015-04-20T12:23:27 [CRITICAL] QNetworkReplyImpl: backend error: caching was enabled after some bytes had been written ] killed: false, code: 1, signal: null

I've seen the issue using both the compiled mac binary running Yosemite as well as when building form source on a machine running Ubuntu 14.04.1.

I was able to find this issue reported in the phridge repository but it just points to phantomjs, without specifying a particular issue https://github.com/peerigon/phridge/issues/23

Below is a minimal script that can reproduce the error (5-10% of the time):

var page = require('webpage').create(),
    system = require('system');

var url = 'http://localhost:4000/screenshot/' + system.args[1];
page.open(url, function(status) {
  if (status !== 'success') {
    phantom.exit(1);
  } else {
    console.log(page.renderBase64('PNG'));
    phantom.exit();
  }
});
Bug QOther stale

Most helpful comment

I can confirm this happens for me too on Mac, with Phantom 2.1.1. The problem seems to happen only with localhost (very-high-speed-connection) and with websockets.. I'll try to provide a small example to reproduce soon

All 27 comments

Thank you for your report. We need some more information from you: specifically, we need the definition of the web page, CGI script, or whatever you have at http://localhost:4000/screenshot/. With just the PhantomJS script, we won't be able to reproduce the problem.

Note that this is almost certainly a bug deep in the guts of Qt and we may wind up asking you to report it to them, but let's not worry about that right now.

Thanks for the quick response, I'm running an angular app locally and below is the document when the page initially loads as well as when everything has loaded, let me know if there is more info I can give.

<!doctype html>
<html ng-app="Centaur">
  <head>
    <title>Title</title>
    <link rel="stylesheet" href="/styles/main.css">
    <link rel="icon" type="image/x-icon" href="/images/favicon.ico">

  </head>
  <body>
    <div class="main-view" ui-view></div>
    <script type="text/javascript" src="/scripts/vendor.js"></script>
    <script type="text/javascript" src="/scripts/app.js"></script>
    <script type="text/javascript">
      url = window.location.hash;
    </script>
    <script type="text/javascript" src="http://localhost:35729/livereload.js"></script>
  </body>
</html>
<html ng-app="Centaur" class="ng-scope"><head><style type="text/css">@charset "UTF-8";[ng\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide:not(.ng-hide-animate){display:none !important;}ng\:form{display:block;}</style>
    <title>Title</title>
    <link rel="stylesheet" href="/styles/main.css">
    <link rel="icon" type="image/x-icon" href="/images/favicon.ico">

  </head>
  <body class="external" cz-shortcut-listen="true">
    <div class="main-view ng-scope" ui-view=""><div class="ng-scope">
  <div class="focus-answer card answer ng-isolate-scope" question="question" discussion="1134df7f">
  <div class="title">
    <div class="question ng-isolate-scope" question="question" has-comparison="hasComparison" adding-comparison="addingComparison">
  <div ng-repeat="questionPart in questionParts" class="ng-scope">

    <div class="display-question ng-scope ng-isolate-scope" question="questionPart" color="blue" ng-click="edit($index)" ng-if="editIndex!=$index">
  <div ng-class="{'signed-in': signedIn}" class="signed-in">
    <span class="resource-icon resource-tickets bg-blue">
      <span class="integration-icon integration-zendesk">
        zendesk
      </span>
    </span>
    <span class="token token-normal" ng-class="{'color-blue': token.type == 'resource'}" ng-repeat="token in tokens">
      Average
    </span><span class="token token-field" ng-class="{'color-blue': token.type == 'resource'}" ng-repeat="token in tokens">
      reopens
    </span><span class="token token-normal" ng-class="{'color-blue': token.type == 'resource'}" ng-repeat="token in tokens">
      of
    </span><span class="token token-resource color-blue" ng-class="{'color-blue': token.type == 'resource'}" ng-repeat="token in tokens">
      tickets
    </span><span class="token token-normal" ng-class="{'color-blue': token.type == 'resource'}" ng-repeat="token in tokens">
      grouped
    </span><span class="token token-normal" ng-class="{'color-blue': token.type == 'resource'}" ng-repeat="token in tokens">
      by
    </span><span class="token token-field" ng-class="{'color-blue': token.type == 'resource'}" ng-repeat="token in tokens">
      assignee
    </span>
  </div>
</div>

  </div>

</div>
    <div class="buttons center-vertical ng-scope" ng-if="signedIn">
      <div tooltip="Favorite" class="button favorite ng-isolate-scope" ng-class="{active: isFavorite(question)}" ng-click="toggleFavorite(question)"><div class="tooltip top hides">
  <div class="bubble">


  </div>
</div>
</div>

      <div ng-if="!focus" tooltip="Expand" class="button expand ng-scope ng-isolate-scope" ng-class="{active: focus}" ng-click="focusOnCurrentQuestion()"><div class="tooltip top hides">
  <div class="bubble">


  </div>
</div>
</div>

    </div>
  </div>
  <div class="viz-container" ng-switch="status">
    <tooltip-content ng-if="!preview" tooltip-position="top" tooltip-hover="false" ng-show="tooltip.showing" class="tooltip-wrapper ng-scope ng-isolate-scope ng-hide" style="left: 1340.1px; top: 305px;"><div class="tooltip top ">
  <div class="bubble">

    <div ng-if="!arkTooltip" ng-transclude="" class="ng-scope">
  <table class="ng-scope">
    <tbody><tr ng-repeat="row in tooltip.table" class="ng-scope">

      <th ng-repeat="col in row" ng-if="$parent.$first" class="ng-binding ng-scope">
        assignee id
      </th><th ng-repeat="col in row" ng-if="$parent.$first" class="ng-binding ng-scope">
        average reopens
      </th>


    </tr><tr ng-repeat="row in tooltip.table" class="ng-scope">



      <td ng-repeat="col in row.data" ng-if="!$parent.$first" class="ng-binding ng-scope">
        Ted
      </td><td ng-repeat="col in row.data" ng-if="!$parent.$first" class="ng-binding ng-scope">
        0
      </td>
    </tr>
  </tbody></table>
</div>
  </div>
</div>
</tooltip-content>



<svg width="100%" ng-attr-height="{{svgHeight}}" height="375">
  <g ng-switch="" on="vizType" ng-attr-transform="translate(0, {{margin.top}})" transform="translate(0, 30)">
    <svg bar-viz="" ng-switch-when="barViz">
  <g class="viz-container" ng-attr-transform="translate({{margin.left}},0)" transform="translate(56,0)">

    <g axis="" ng-if="!preview" class="y axis" letter="y" tick-width="1833" scale="heightScale">
    <g class="tick" transform="translate(0,275)" style="opacity: 1;"><line x2="1833" y2="0"></line><text dy=".32em" x="-3" y="0" style="text-anchor: end;">0.0</text></g><g class="tick" transform="translate(0,137.5)" style="opacity: 1;"><line x2="1833" y2="0"></line><text dy=".32em" x="-3" y="0" style="text-anchor: end;">0.5</text></g><g class="tick" transform="translate(0,0)" style="opacity: 1;"><line x2="1833" y2="0"></line><text dy=".32em" x="-3" y="0" style="text-anchor: end;">1.0</text></g><path class="domain" d="M0,0H0V275H0"></path></g>
    <g clip-path="url(#cliphkfccocvdcissjor)">
      <g ng-attr-transform="translate({{-shifted.amount*(vizWidth - width)}},0)" transform="translate(0,0)">
        <g class="page" ng-attr-transform="translate({{pageIndex * (barWidth + barMargin)}},0)" transform="translate(0,0)">
          <g ng-repeat="barLabel in page" ng-attr-transform="translate({{$index*(barWidth+barMargin)}},0)" class="ng-scope" transform="translate(0,0)">
            <rect class="bar-background" ng-mouseover="showTooltip(pageIndex + $index, barLabel)" ng-mouseleave="tooltip.showing=false" ng-attr-width="{{barWidth}}" height="40" ng-attr-y="{{height-35}}" width="362.6" y="240">
            </rect>
            <rect ng-repeat="c in config" class="bar blue" ng-attr-width="{{barWidth/config.length}}" ng-if="values[barLabel][$index]" ng-attr-height="{{height - heightScale(values[barLabel][$index])}}" ng-attr-x="{{$index*(barWidth+barMargin)/config.length}}" ng-attr-y="{{heightScale(values[barLabel][$index])}}" ng-mouseover="showTooltip(pageIndex + $parent.$parent.$index, barLabel)" ng-mouseleave="tooltip.showing=false" width="362.6" height="275" x="0" y="0">
            </rect>
            <text class="tick ng-binding ng-scope" ng-if="!preview" ng-attr-transform="translate({{barWidth/2}},{{height + 15}})" transform="translate(181.3,290)">
              Testing
            </text>
          </g><g ng-repeat="barLabel in page" ng-attr-transform="translate({{$index*(barWidth+barMargin)}},0)" class="ng-scope" transform="translate(367.6,0)">
            <rect class="bar-background" ng-mouseover="showTooltip(pageIndex + $index, barLabel)" ng-mouseleave="tooltip.showing=false" ng-attr-width="{{barWidth}}" height="40" ng-attr-y="{{height-35}}" width="362.6" y="240">
            </rect>
            <rect ng-repeat="c in config" class="bar blue" ng-attr-width="{{barWidth/config.length}}" ng-if="values[barLabel][$index]" ng-attr-height="{{height - heightScale(values[barLabel][$index])}}" ng-attr-x="{{$index*(barWidth+barMargin)/config.length}}" ng-attr-y="{{heightScale(values[barLabel][$index])}}" ng-mouseover="showTooltip(pageIndex + $parent.$parent.$index, barLabel)" ng-mouseleave="tooltip.showing=false" width="362.6" height="6.346153846153868" x="0" y="268.65384615384613">
            </rect>
            <text class="tick ng-binding ng-scope" ng-if="!preview" ng-attr-transform="translate({{barWidth/2}},{{height + 15}})" transform="translate(181.3,290)">
              Andrew Vigneault
            </text>
          </g><g ng-repeat="barLabel in page" ng-attr-transform="translate({{$index*(barWidth+barMargin)}},0)" class="ng-scope" transform="translate(735.2,0)">
            <rect class="bar-background" ng-mouseover="showTooltip(pageIndex + $index, barLabel)" ng-mouseleave="tooltip.showing=false" ng-attr-width="{{barWidth}}" height="40" ng-attr-y="{{height-35}}" width="362.6" y="240">
            </rect>

            <text class="tick ng-binding ng-scope" ng-if="!preview" ng-attr-transform="translate({{barWidth/2}},{{height + 15}})" transform="translate(181.3,290)">
              Thor
            </text>
          </g><g ng-repeat="barLabel in page" ng-attr-transform="translate({{$index*(barWidth+barMargin)}},0)" class="ng-scope" transform="translate(1102.8000000000002,0)">
            <rect class="bar-background" ng-mouseover="showTooltip(pageIndex + $index, barLabel)" ng-mouseleave="tooltip.showing=false" ng-attr-width="{{barWidth}}" height="40" ng-attr-y="{{height-35}}" width="362.6" y="240">
            </rect>

            <text class="tick ng-binding ng-scope" ng-if="!preview" ng-attr-transform="translate({{barWidth/2}},{{height + 15}})" transform="translate(181.3,290)">
              Ted
            </text>
          </g><g ng-repeat="barLabel in page" ng-attr-transform="translate({{$index*(barWidth+barMargin)}},0)" class="ng-scope" transform="translate(1470.4,0)">
            <rect class="bar-background" ng-mouseover="showTooltip(pageIndex + $index, barLabel)" ng-mouseleave="tooltip.showing=false" ng-attr-width="{{barWidth}}" height="40" ng-attr-y="{{height-35}}" width="362.6" y="240">
            </rect>

            <text class="tick ng-binding ng-scope" ng-if="!preview" ng-attr-transform="translate({{barWidth/2}},{{height + 15}})" transform="translate(181.3,290)">
              Ryan Atallah
            </text>
          </g>
        </g>
      </g>
    </g>


  </g>

  <clipPath id="cliphkfccocvdcissjor">
    <rect ng-attr-width="{{width}}" ng-attr-height="{{height+margin.bottom}}" width="1833" height="345">
    </rect>
  </clipPath>

  <g ng-if="!preview" class="ng-scope"> 
    <g ng-attr-transform="translate({{width/2 + margin.left}},{{height + margin.bottom - labelPadding}})" transform="translate(972.5,325)">
      <text class="x label ng-binding">
        Assignee ID
      </text>
    </g>
    <g ng-attr-transform="translate({{labelPadding + labelHeight}},{{height/2}})" transform="translate(30,137.5)">
      <text class="y label ng-binding">
        Average Reopens
      </text>
    </g>
  </g>
</svg>


  </g>
</svg>
</viz>

    </div>
</div>
</div>
</div>
    <script type="text/javascript" src="/scripts/vendor.js"></script>
    <script type="text/javascript" src="/scripts/app.js"></script>
    <script type="text/javascript">
      url = window.location.hash;
    </script>
    <script type="text/javascript" src="http://localhost:35729/livereload.js"></script>
</body></html>

We need a complete and self-contained test page: something that we can run
for ourselves. Ideally it would be reduced to the minimum amount of code
and data necessary to trigger the problem, with dependencies on third-party
code eliminated, and packed into one file. If specific server
configuration is required, we need to know that too.

I'm sorry to have to ask you to do a bunch more work, but we really can't
make any forward progress without it.

Here are some guidelines for minimizing test cases that may be helpful:

https://wiki.mozilla.org/QA/Minimal_Test_Cases
http://sscce.org/
http://stackoverflow.com/help/mcve
http://www.achievo.org/wiki/Minimal_testcase

Had this problem as well on some internal code. The workaround I found is to prophylactically turn on disk cache.

Eg. phantomjs --disk-cache=true

I can confirm this happens for me too on Mac, with Phantom 2.1.1. The problem seems to happen only with localhost (very-high-speed-connection) and with websockets.. I'll try to provide a small example to reproduce soon

I've got an Ember app that uses websockets and I'm hitting the same issue.

I have a reproduction (tested on Mac only), there is a lot of files, but at least it's spitting that error so maybe you can catch it
https://github.com/javascriptlove/phantomjs-qnetworkreplyimpl

@javascriptlove Thank you!
This error happens when you have disk caching disabled. If you run phantomjs with --disk-cache=yes then the error will disappear.

@Vitallium someone else mentioned this earlier. IIRC I tried this and it didn't help.

@wagenet test case? I tried the sample from @javascriptlove and it worked. Also, the new PhantomJS with new WebKit doesn't have this error.

@Vitallium did you try to run that phantom script again? i noticed first time there's no error, and then there is it all the time.. btw what OS did you try on?

@javascriptlove yes, I tried. I got this error on each launch. I am on macOS Sierra (PJS 2.1.1)

Oh ok, i thought "it worked" means it is fine.. nvm

@javascriptlove no, sorry, I meant that with your sample it reproduces 100%.

I can reproduce it as well, but only in a very specific context, and randomly:
On our continuous integration, we run functional tests using Cucumber for java, Selenium and PhantomJS 2.1.13, on an Ubuntu.
The first test to run after the server is started fails due to this error most of the time. All other tests pass.

The tests nevers fails when we run them locally on Windows.

The workaround "--disk-cache=yes" did not work for us.

--disk-cache=yes also didint work for us, once it a blue moon it would work as expected, but 80%+ of the test runs fail with this error.

Is there any progress being made on this issue. We are experiencing this issue and it appears we have the exact same behavior as @javascriptlove described.

I noticed first time there's no error, and then there is it all the time..

Also reporting this issue using Argus Eyes / phantomJS 2.1.7 to test visual regressions against a local site on macOS. [CRITICAL] QNetworkReplyImpl: backend error: caching was enabled after some bytes had been written

On OS X - node index.js --disk-cache=true works for me!!
package - "phantom": "^4.0.2"

I received this error when I started optimising my code. It seems to only happen on really fast page loads. Although far from ideal, This hack has made the problem go away.

 <head>
...
<script>

            // issue with phatom js https://github.com/peerigon/phridge/issues/23 https://github.com/ariya/phantomjs/issues/13165
            // however this hack seems to fix it
                function pausecomp(ms) {
                    ms += new Date().getTime();
                    while (new Date() < ms){}
                } 
                pausecomp(100);
            </script>
</head>

As a contribution, the error is trigged here: https://github.com/qt/qtbase/blob/v5.9.1/src/network/access/qnetworkreplyhttpimpl.cpp#L2284
It looks like phantomjs is trying to enable cache after the page already started downloading. Even when disk cache is disable by default. The workaround to enable disk cache prevent this issue because in this mode the cache will be enabled from start. But, What happen if use cache is not desired?

Note that this fix: https://github.com/ariya/phantomjs/issues/13165#issuecomment-316260715 is going to use CPU as much as possible to block temporary the execution. No so efficient.

@josenobile

Note that this fix: #13165 (comment) is going to use CPU as much as possible to block temporary the execution. No so efficient.

I agree 100% but I would love another decent solution --disk-cache=true doesn't make any difference for me

Happened to me when I tried to load multiple stylesheets in the HTML file head, namely bootstrap (minified).

I moved to dynamically load the stylesheet and the problem is resolved.

Due to our very limited maintenance capacity (see #14541 for more details), we need to prioritize our development focus on other tasks. Therefore, this issue will be automatically closed. In the future, if we see the need to attend to this issue again, then it will be reopened. Thank you for your contribution!

Was this page helpful?
0 / 5 - 0 ratings