title: What's the net::ERR_HTTP2_PROTOCOL_ERROR about?
body: <p>I'm currently working on a website, which triggers a <code>net::ERR_HTTP2_PROTOCOL_ERROR 200</code> error on Google Chrome. I'm not sure exactly what can provoke this error, I just noticed it pops out only when accessing the website in HTTPS. I can't be 100% sure it is related, but it looks like it prevents JavaScript to be executed properly.</p>
  <p>For instance, the following scenario happens :</p>
  <ol>
  <li><p>I'm accessing the website in HTTPS</p>
  </li>
  <li><p>My Twitter feed integrated via <a href="https://publish.twitter.com" rel="noreferrer">https://publish.twitter.com</a>  isn't loaded at all</p>
  </li>
  <li><p>I can notice in the console the ERR_HTTP2_PROTOCOL_ERROR</p>
  </li>
  <li><p>If I remove the code to load the Twitter feed, the error remains</p>
  </li>
  <li><p>If I access the website in HTTP, the Twitter feed appears and the error disappears</p>
  </li>
  </ol>
  <p>Google Chrome is the only web browser triggering the error: it works well on both Edge and Firefox.
  (NB: I tried with Safari, and I have a similar <code>kcferrordomaincfnetwork 303</code> error)</p>
  <p>I was wondering if it could be related to the header returned by the server since there is this '200' mention in the error, and a 404 / 500 page isn't triggering anything.</p>
  <p>Thing is the error isn't documented at all. Google search gives me very few results. Moreover, I noticed it appears on very recent Google Chrome releases; the error doesn't pop on v.64.X, but it does on v.75+ (regardless of the OS; I'm working on Mac tho).</p>
  <hr />
  <p>Might be related to <a href="https://stackoverflow.com/questions/49927327/website-ok-on-firefox-but-not-on-safari-kcferrordomaincfnetwork-error-303-neit">Website OK on Firefox but not on Safari (kCFErrorDomainCFNetwork error 303) neither Chrome (net::ERR_SPDY_PROTOCOL_ERROR)</a></p>
  <hr />
  <p>Findings from further investigations are the following:</p>
  <ul>
  <li><strong>error doesn't pop on the exact same page if server returns 404 instead of 2XX</strong></li>
  <li>error doesn't pop on local with a HTTPS certificate</li>
  <li>error pops on a different server (both are OVH's), which uses a different certificate</li>
  <li>error pops no matter what PHP version is used, from 5.6 to 7.3 (framework used : Cakephp 2.10)</li>
  </ul>
  <p>As requested, below is the returned header for the failing ressource, which is the whole web page. Even if the error is triggering on each page having a HTTP header 200, those pages are always loading on client's browser, but sometimes an element is missing (in my exemple, the external Twitter feed). Every other asset on the Network tab has a success return, except the whole document itself.
  <a href="https://i.stack.imgur.com/ZkdHo.png" rel="noreferrer"><img src="https://i.stack.imgur.com/ZkdHo.png" alt="line that failed in console" /></a></p>
  <p>Google Chrome header (with error):</p>
  <p><a href="https://i.stack.imgur.com/0wCrD.png" rel="noreferrer"><img src="https://i.stack.imgur.com/0wCrD.png" alt="Chrome header" /></a></p>
  <p>Firefox header (without error):</p>
  <p><a href="https://i.stack.imgur.com/AAtn8.png" rel="noreferrer"><img src="https://i.stack.imgur.com/AAtn8.png" alt="Firefox header" /></a></p>
  <p>A <code>curl --head --http2</code> request in console returns the following success:</p>
  <pre><code>HTTP/2 200 
  date: Fri, 04 Oct 2019 08:04:51 GMT
  content-type: text/html; charset=UTF-8
  content-length: 127089
  set-cookie: SERVERID31396=2341116; path=/; max-age=900
  server: Apache
  x-powered-by: PHP/7.2
  set-cookie: xxxxx=0919c5563fc87d601ab99e2f85d4217d; expires=Fri, 04-Oct-2019 12:04:51 GMT; Max-Age=14400; path=/; secure; HttpOnly
  vary: Accept-Encoding
  </code></pre>
  <hr />
  <p>Trying to go deeper with the chrome://net-export/ and <a href="https://netlog-viewer.appspot.com" rel="noreferrer">https://netlog-viewer.appspot.com</a> tools is telling me the request ends with a RST_STREAM :</p>
  <pre><code>t=123354 [st=5170]    HTTP2_SESSION_RECV_RST_STREAM
                        --&gt; error_code = &quot;2 (INTERNAL_ERROR)&quot;
                        --&gt; stream_id = 1
  </code></pre>
  <p>For what I read in <a href="https://stackoverflow.com/questions/28736463/rst-stream-frame-in-http2">this other post</a>, &quot;<em>In HTTP/2, if the client wants to abort the request, it sends a RST_STREAM. When the server receives a RST_STREAM, it will stop sending DATA frames to the client, thereby stopping the response (or the download). The connection is still usable for other requests, and requests/responses that were concurrent with the one that has been aborted may continue to progress.
  [...]
  It is possible that by the time the RST_STREAM travels from the client to the server, the whole content of the request is in transit and will arrive to the client, which will discard it. However, for large response contents, sending a RST_STREAM may have a good chance to arrive to the server before the whole response content is sent, and therefore will save bandwidth.</em>&quot;</p>
  <p>The described behavior is the same as the one I can observe. But that would mean the browser is the culprit, and then I wouldn't understand why it happens on two identical pages with one having a 200 header and the other a 404 (same goes if I disable JS).</p>