38

I and a few of my colleagues got the net::ERR_SPDY_PROTOCOL_ERROR error.

We use ngnix version 1.8.0. The error is not stable (hard to replicate), and the Ngnix error log doesn't have this error.

How would you advise we catch and resolve this?

Ahmed Fasih
  • 5,979
  • 3
  • 43
  • 86
TheMrbikus
  • 673
  • 2
  • 8
  • 14

14 Answers14

20

I came across this question when trying to find help for the problem I was facing with ERR_SPDY_PROTOCOL_ERROR on Chrome. Thought this might benefit others.

Our situation / solution: We use an AWS Application Load Balancer connected to EC2 instances. One of the scripts we run on EC2 proxies requests from the client browser. We recently updated the script - no relevant changes - and noticed that both Chrome and Safari requests to the proxy script started failing. Chrome showed the ERR_SPDY_PROTOCOL_ERROR error and, when we dug in to it, we could see this request was using HTTP/2. Firefox requests continued to work fine.

Our solution: we switched off HTTP/2 support in the ALB. Immediately solved the problem.

AWS CLI command:

aws elbv2 modify-load-balancer-attributes --load-balancer-arn <your_load_balancer_arn> --attributes Key=routing.http2.enabled,Value=false
CharlesA
  • 3,764
  • 2
  • 23
  • 29
16

I had the same problem, check if you have enough space in the Nginx partition/HDD, we add some and it worked for us.

Simon Iribarren
  • 161
  • 1
  • 7
13

TL;DR: if you are caching assets, then check the drive space on your nginx server.

Our Scenario

I'm not sure where to post my answer to this since it might be an edge case when getting the ERR_SPDY_PROTOCOL_ERROR in Chrome (and the equivalent "failure to load resource" error in Firefox). But this post helped me narrow down the culprit. It wasn't headers, gzip, redirects, or adblock/ublock.

We have 2 web applications deployed from the machine, and both were running perfectly fine. Recently, we deployed one of the applications with changes to cached assets. Once the deploy completed, we immediately got the ERR_SPDY_PROTOCOL_ERROR from Chrome. Interestingly enough, it was receiving an HTTP 200 and if you navigated to the asset directly, Chrome would render the asset. However, loading the asset on a page would cause it to fail.

Interstingly enough, the other web application was perfectly fine. Investigating the net internals on Chrome, we discovered the server was closing the connection. After several hours, we determined that it was because our nginx server had run out drive space. I don't know why that would cause the assets to load properly when you navigate to them directly, but fail when you load a page, but clearing out space instantly fixed the problem.

Kyle Schutt
  • 301
  • 2
  • 6
5

As you can tell from the other answers, a lot of different things can cause this. For me, I had a malformed header that other browsers were just ignoring (an extra :). The only answer for this is a debugging tip, checkout Chrome's net-internals events while loading the broken page: chrome://net-internals/#events

For me, I knew it was a header issue when I saw this line

t=65422 [st=53]      HTTP_TRANSACTION_READ_HEADERS  [dt=4]
                 --> net_error = -337 (ERR_SPDY_PROTOCOL_ERROR) 

After removing the extra : from the header response, HTTP/2 began working in Chrome. I suggest getting a raw response from your server and doing very close inspection to ensure there are no syntax errors.

lightswitch05
  • 8,149
  • 6
  • 45
  • 71
4

There seem to be many potential causes. One I hit today was the header line

add_header X-Frame-Options: deny;

Current chrome will barf on that with ssl+http2 for some reason. Other X-Frame headers don't seem to be a problem.

Hal Burgiss
  • 925
  • 1
  • 7
  • 11
  • 5
    also chrome://net-internals was very helpful in debugging – Metagrapher Jan 24 '18 at 08:37
  • The issue in the header line above appears to be the colon, it should not be there according to the [nginx documentation](http://nginx.org/en/docs/http/ngx_http_headers_module.html). I had the same issue, it appears the http2 parser is somehow stricter and does not ignore the colon anymore. (See also: https://trac.nginx.org/nginx/ticket/1409) – marv51 Jul 27 '18 at 23:06
3

This is a known issue that exists between Chromium browsers and certain antivirus programs such as AVG and Avast, especially when using a SSL connection. It cannot be resolved on the user's end. It's up to website developers to prevent this issue from happening.

The documentation for web developers is here: http://dev.chromium.org/spdy/spdy-best-practices

Here are some helpful hints for developers that are not specifically mentioned in that article:

  • Be extremely careful when using headers and redirects, especially 301 and 302's
  • Keep all your includes in or under the same directory as your domain name access, not above the directory in the server. Antivirus cannot access them there. To protect your include files, create a .htaccess file in the includes directory and simply write one line: Deny from all
  • Enable Gzip compression. If you use cPanel, this can be done in your Website Optimization settings.
  • Keep your .htaccess file simple. Switching server outputs to create different file extensions and redirecting user clients will create unnecessary conflict.

In my experience, this issue only seems to occur when using Sessions to store and pass data. Cookies, Get and Post seem to not be affected.

Hope this helps.

AnarchyOutlaw
  • 167
  • 2
  • 6
3

For me it was Nginx configuration that didn't allow OPTIONS method. I had whitelisted GET|PUT|POST|DELETE only, so when Chrome tried to send OPTIONS method, for God knows why**, the error was reproduced.

Open up Firefox and repeat the request, then look at the Network inspector to check if any OPTIONS requests are being sent.

** probably to check for X-Frame-Options or HSTS verification.

Nj Subedi
  • 317
  • 4
  • 15
1

I had a site doing that, it turned out to be someone forgot to put "Location: " in a PHP redirect on the first line of index.php, invalidating the header. Apparently only Chrome cared though, the rest of the browsers still loaded it fine.

David Bell
  • 143
  • 1
  • 8
1

As with the OP, this was an intermittent issue for me and only happening on AJAX requests > 2mb in size.

The problem started occurring after we moved from an AWS classic ELB to ALB.

I solved this by uninstalling Chrome, deleting my user profile (On mac delete the contents of ~/Library/Application Support/Google/Chrome), then reinstalling.

greg
  • 6,626
  • 13
  • 51
  • 71
1

I've seen this error recently after a server upgrade.

I was seeing it for all users in Chrome, but only intermittently.

I was able to resolve it for all users by getting them to use Chrome's 'Empty Cache and Hard Reload' refresh function for the site. (F12 for Chrome tools, right click on refresh button)

I suspect it related to something cached about the SSL certs being used.

Josh
  • 2,994
  • 2
  • 17
  • 22
1

Check the location of your proxy cache path - check it exists, has space, and that the permissions and owner allow the nginx process to write to the path.

e.g. nginx.conf (snippet)

proxy_cache_path /proxy_cache levels=1:2 keys_zone=danger_zone:10m inactive=60m;

... then check the /proxy_cache path is owned and writable by nginx.

Nick Grealy
  • 18,859
  • 9
  • 84
  • 100
1

In my case, I have solved this by increasing the chunk size :

http2_chunk_size             300k;
iMartin
  • 59
  • 2
1

If you're getting

ERR_HTTP2_PROTOCOL_ERROR

OR

ERR_SPDY_PROTOCOL_ERROR

in Chrome or Safari browser by using Nginx Content-Security-Policy, first inspect this issue by accessing chrome hidden interface: chrome://net-internals/#events and selecting "live HTTP/2 sessions" button under HTTP/2 tab.

If you get anything like below as a result against your domain after a refresh:

HTTP2_SESSION_RECV_INVALID_HEADER

--> error = "Invalid character in header name."

You should write CSP header in following method:

add_header Content-Security-Policy "<values>";

This method worked fine for me.

NOTE: White spaces are not allowed in CSP. Use white space to differentiate the policy parameter and its value only. To reproduce this issue in chrome, you can use add_header Content-Security-Policy: "<values>"; which have additional : which will consider as invalid.

Community
  • 1
  • 1
mrijinm
  • 21
  • 2
  • Thanks a lot! That was the very error I was encountering. Turns out I had a similar problem - a typo while setting the header "charset=utf-8" instead of "charset: utf-8". – SearchingSolutions Nov 15 '19 at 11:29
0

Our current structure was

AWS ELB=>Nginx=>JBoss

It prompted us the the same crome error ERR_SPDY_PROTOCOL_ERROR

It worked properly without http2 which is by default enabled by ELB, we didn't want it to be disabled. On further investigation it was noticed that our JBoss server was compressing the response.We disabled the it and everything working fine.