Inconsistent ERR_HTTP2_SERVER_REFUSED_STREAM error on page-load
Asked Answered
G

4

10

I do have at least two wordpress sites which very inconsistently throw a varying number of net::ERR_HTTP2_SERVER_REFUSED_STREAM errors. When these errors occur the number of errors thrown highly varies from page-load to page-load (or reload) from say 4 requests with that error to about 60 and sometimes even more (if the page has some many requests). The actually affected ressources/requests seem completly random and therefore don't leave any clue where this is coming from.

If these errors occur their occurrence mostly persists (when doing a simple page refresh or hard refresh) until the browser is restarted. Seldomly they even stay after a restart as well.

When this hiccup does happen and the browser/system gets in this faulty state, these errors also happen in the wordpress backend loading basic files like .../wp-includes/js/wp-lists.min.js?ver=5.7 and similar.

At least two users have experienced this behaviour in Chrome, Opera and Edge while being logged-in to and -out of wordpress. In Opera and Edge we do not have any browser extensions installed. As far as we know other users never had this issue even though some of them visited the site many times.

What might be the reasons for this and/or what might be a way to solve it?


List of Plugins installed on both sites:


Geniagenial answered 10/3, 2021 at 20:0 Comment(4)
Do you have any security plugin installed on your site? I faced similar issue a week ago. The site had 2 security plugins installed together and I uninstall one of them and it fixed the issue for me.Pastorship
Mmmh, I guess not a security plugin in classic sense, but I do have a Password Protection Plugin installed (see: Password Protect WordPress Lite in the added list of installed plugins). With the plugin I have a sitewide protection enabled as the site is not for public access. ... Before I will be able to deactivate the plugin and check if this solves the issue I'll probably have to look for some kind of alternative in limiting the access to the site, but I'll have to clarify that. I'll do that tomorrow. ... Thanks for the hint in that direction.Geniagenial
Minor Update: We have disabled the plugin and very briefly afterwards the other user, who experienced these errors, had them again. But, as it was very immediate after the deactivation of the plugin that could be browser- / caching-related (?). ... Besides that one occurence we've had no errors since then. As the errors even before the deactivation only happened seemingly arbitrarily, we do not know (yet), if the issue is actually solved. ...Geniagenial
Update: The error still occured after disabling the `Password Protect WordPress Lite´ Plugin. So in our case a security plugin wasn't the cause.Geniagenial
Z
11

This is not related to WordPress. It's related to either Apache or Nginx using the HTTP/2 standard.

REFUSED_STREAM (0x7): The endpoint refused the stream prior to performing any application processing (see Section 8.1.4 for details).

It can either come from too many concurrent streams:

Endpoints MUST NOT exceed the limit set by their peer. An endpoint that receives a HEADERS frame that causes its advertised concurrent stream limit to be exceeded MUST treat this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR or REFUSED_STREAM. The choice of error code determines whether the endpoint wishes to enable automatic retry (see Section 8.1.4) for details).

It can also be sent during a Push Response operation:

If the client determines, for any reason, that it does not wish to receive the pushed response from the server or if the server takes too long to begin sending the promised response, the client can send a RST_STREAM frame, using either the CANCEL or REFUSED_STREAM code and referencing the pushed stream's identifier.

Or if the client is trying to connect using HTTP/1.1:

Servers that don’t wish to process the HTTP/1.1 response should reject stream 1 with a REFUSED_STREAM error code immediately after sending the connection preface to encourage the client to retry the request over the upgraded HTTP/2 connection.

There is no way for me to pinpoint what is happening during those requests, as it can have multiple reasons, as stated above.

So I suggest you a couple of options:

  • Pass your site's traffic through Cloudflare, so they act as a middle-man for these connections and normalize the requests sent to your server
  • You can increase the SETTINGS_MAX_CONCURRENT_STREAMS to minimize the risk of sending a REFUSED_STREAM. If you use Nginx, you can see how to do this here: http://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_max_concurrent_streams
  • If you don't know how to do the above, contact your hosting company and ask them to do it for you and upgrade your Nginx version, as some older versions are known to have issues.
  • Disable HTTP/2 in Nginx. How to disable http2 in nginx
  • As a last resource, you can migrate to another hosting company.

If you use Apache, everything I said above applies to it as well.

Zebulon answered 27/3, 2021 at 1:8 Comment(11)
Thank you for your reply. As we are no server admins by any means, we contacted our hosting company, if the suggested changes can be made. In that regard: Do you know, if disabling HTTP/2 can have any side effects (on other projects)? ... Besides these suggestions: If I understand it correctly the third quote states that the error may also be caused by the client-side. As far as I can tell, that would make more sense. That's because it seems to us that not all users experience these errors and additionally because the errors often disappear, when the browser is restarted.Geniagenial
It's unlikely to be a client issue, as it would happen everytime with that client. It's more likely a server-load issue, such as dropping connections depending on the amount of traffic it is handling at that time. You could increase your max number of concurrent streams, as per the link in the answer. HTTP/2 is pretty new technology, it's safe to downgrade to HTTP/1.1, which is the default of the internet nowadays.Zebulon
I'd recommend you asking your hosting company to tweak Nginx/Apache settings before giving up and downgrading to HTTP/1.1, though.Zebulon
@Geniagenial are you passing your traffic through Cloudflare?Zebulon
I don't think so, but unfortunately I cannot say that for sure. I assume to be certain about it, I have to ask our hosting company. I just tried that, but I didn't reach anybody. So I'll try that again tomorrow and respond again when I have reliable information.Geniagenial
@Geniagenial OK. Passing your traffic through CloudFlare might solve your issues, as Cloudflare will act as a reverse-proxy, normalizing the HTTP responses it receives and the ones it sends to your server. Also, CloudFlare is something you should be using anyway to protect your site from bots and hackers trying to scan your site for vulnerabilities.Zebulon
Passing your traffic through Cloudflare is very easy, it is set-up per-domain. You basically create a Cloudflare account, and change your domain DNS to Cloudflare's. It might be a little more complicated if the domain uses email from the server, such as through webmail.somedomain.com instead of using Google for Business e-mails, for instance, in which case you'd need some special DNS rules for e-mails.Zebulon
Ok, so our hosting company just helped me out. Previously the site wasn't passing its traffic through Cloudflare. Our hosting package (a managed server) does include an option to enable hosting via Cloudflare directly through its user interface. Instead of activating and configuring the passing through directly via Cloudflare I decided (maybe prematurely) to use our hosters interface as a start and left all settings set to its defaults. ... As of now loading the site all requests / resources still point to the IP-Address of our server, but I was told that that should change soon.Geniagenial
So after switching to host / rout our site via Cloudflare the errors never occurred again. So I just marked this as the correct answer. (Sorry, for the delayed response, but I had some personal issues).Geniagenial
Thanks for the feedback, @SunnyRed. I have updated the answer to include Cloudflare as the first proposed solution.Zebulon
Disabling http2 on our Kong proxy resolved this problem for us.Languedoc
G
1

I do have at least two wordpress sites which very inconsistently throw a varying number of net::ERR_HTTP2_SERVER_REFUSED_STREAM errors. When these errors occur the number of errors thrown highly differs from say 4 requests to about 60 and sometimes even more (if the page has enough requests),

As you said,the count of stream error is more than requests. A possibie explains is stream is push streams which has even stream id. Push stream is initiated by server side. In cotrast, stream initated by client side has odd id.

Why error counts so much?

We follow key error word to try to find some roadmap. search key word ERR_HTTP2_SERVER_REFUSED_STREAM in chromium github repo

We get the following sutuation to reply ERROR_CODE_REFUSED_STREAM.

  • Browser handles server side stream RST frame (SpdySession::OnGoAway).RST frame means closing stream but not closing session. we may recevive error ERR_HTTP2_SERVER_REFUSED_STREAM

  • Browser handles server side stream Goway frame (SpdySession::OnGoAway). Goway frame means closing session. Server side request goway frame without any error(spdy::ERROR_CODE_NO_ERROR). we may recevive error ERR_HTTP2_SERVER_REFUSED_STREAM

The error counts is far more than the requests. So we may be led to stage concultion.
Server side sent RST frame with high probability.

Now we keep digging in.

search key word ERROR_CODE_REFUSED_STREAM in chromium github repo

Server may sent ERROR_CODE_REFUSED_STREAM with the following suituation:

  • When session property enable_push_ is off, but try to create push stream.
  • session state goes to STATE_GOING_AWAY, but receive push stream
  • Wrong Push stream without ":url" header
  • Only http scheme allowed for cross origin push by trusted proxy. If not, get refused.
  • Pushed URL must have https scheme
  • Certificate does not match pushed URL.
  • Duplicate pushed stream with the same url.
  • ERR_TIMED_OUT or ERR_HTTP2_CLIENT_REFUSED_STREAM

Useful utility

use debug tools to get more info.

chrome://net-internals/http2#events

or

chrome://net-export/

About server push news

Chrome to remove server push

Gaddis answered 27/3, 2021 at 4:46 Comment(1)
If I understand you correctly, I assume that I misphrased the relation between the number of errors thrown and the number of page-requests. As far as I have observed the number of errors does not exceed the number of page-requests. If errors occur, it's just the case that the actual number of errors does vary heavily from page-load to page-load and the actual affected ressources/request don't leave any hint, where the errors cause is coming from. ... I edited the question to try to clarify that. ... Thanks for the utility notice/suggestion. I took a look into it and try to keep it in mind.Geniagenial
G
1

I solved my ERR_HTTP2_SERVER_REFUSED_STREAM by setting a higher value for keep-alive-requests in my ingress-nginx:

apiVersion: v1
kind: ConfigMap
metadata:
  name: ingress-nginx-mse-controller
  namespace: mse
data:
  enable-brotli: "true"
  use-http2: "true"
  keep-alive-requests: "9999"

The default value for keep-alive-requests is 1000.

http://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_requests

If you want to specify "unlimited" there is no such value; just set a high value. The higher the value the more memory your server will consume.

More info here: https://serverfault.com/a/425130/241371 and here: https://trac.nginx.org/nginx/ticket/2155

Gait answered 29/7, 2023 at 15:12 Comment(0)
B
0

I got the same error 2023 in Chrome connection to k8s nginx container, that had 100's of small .js files to load. "net::ERR_HTTP2_SERVER_REFUSED_STREAM" No problem with Firefox, only Chrome.

After trying all kinds of nginx settings it was resolved for me by upgrading my ingress-nginx helm chart from 4.2.0 to latest 4.6.0 :) https://github.com/kubernetes/ingress-nginx/releases

Bordeaux answered 4/4, 2023 at 8:27 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.