ERR_SPDY_PROTOCOL_ERROR on one site, not others on the same nginx server

515 views
Skip to first unread message

David Bell

unread,
Jul 13, 2017, 3:45:49 AM7/13/17
to Chromium-discuss
Hi, I posted this on the Chrome Help Forum and was advised to post it here:

--------------------------------------------------------------------------------------------------------------------------

Hi, I've been looking into the cause of this for a few days now and can't seem to shed any light on it.

I have a server running nginx with a few websites on, with conf files that have been copied from one to the next and very little changes made (generally just root folder & domain & logs/certs). One, and only one of the sites always breaks in Chrome with ERR_SPDY_PROTOCOL_ERROR, it works fine in other browsers and the other sites all work fine in Chrome.

I have compared my conf files and as mentioned above, bar the obvious essential changes found them to be the same. I have checked OpenSSL isn't too old (1.0.2l). I have examined SPDY connections in Chrome only to find it has none, but I have also examined HTTP2 and found an entry for the site with the "SPDY" problem, which I thought was a bit weird.

I've run out of ideas, so I was wondering if anyone could maybe shed some light on what the actual error is.


A non-affected site on the same server: https://1066ts.co.uk/

--------------------------------------------------------------------------------------------------------------------------

Some extra points to note:
  • It's a cloud server that we have full access to.
  • Problem persists across all machines and different networks I've tested it on, even Chrome on my phone.
  • It does not affect any other browsers tested.
  • I have not had any examples of it not occurring in Chrome, even in incognito mode.
  • My personal opinion is that the fact the error mentions SPDY is a red-herring because of the mentioned "no SPDY yet HTTP2 connection showing" above.

If anyone could help we would be very grateful as it's probably costing us sales. Thanks :)

Chris Bentzel

unread,
Jul 13, 2017, 8:19:14 AM7/13/17
to dave....@gmail.com, Chromium-discuss, b...@chromium.org
+Bence Béky

SPDY was an earlier protocol that morphed into HTTP/2. Sometimes the names still exist. 

chorme://net-internals dump shows this for me. See the RECV_INVALID_HEADER frame. Not quite sure what's going on there.


It=224090 [st= 0] HTTP2_SESSION_PING
                   --> is_ack = false
                   --> type = "sent"
                   --> unique_id = 1
t=224090 [st=  0]  HTTP2_SESSION_SEND_HEADERS
                   --> exclusive = true
                   --> fin = true
                   --> has_priority = true
                   --> :method: GET
                       :authority: book1066ts.co.uk
                       :scheme: https
                       :path: /
                       cache-control: max-age=0
                       upgrade-insecure-requests: 1
                       user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3156.0 Safari/537.36
                       accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
                       accept-encoding: gzip, deflate, br
                       accept-language: en-US,en;q=0.8,de;q=0.6
                   --> parent_stream_id = 0
                   --> source_dependency = 29745 (HTTP_STREAM_JOB)
                   --> stream_id = 5
                   --> weight = 256
t=224108 [st= 18]  HTTP2_SESSION_PING
                   --> is_ack = true
                   --> type = "received"
                   --> unique_id = 1
t=224502 [st=412]  HTTP2_SESSION_RECV_INVALID_HEADER
                   --> header_name = "/redeemvoucher"
                   --> header_value = ""
t=224502 [st=412]  HTTP2_SESSION_SEND_RST_STREAM
                   --> description = "Could not parse Spdy Control Frame Header."
                   --> error_code = "1 (PROTOCOL_ERROR)"
                   --> stream_id = 5
t=224503 [st=413]  HTTP2_SESSION_RECV_DATA
                   --> fin = false
                   --> size = 211
                   --> stream_id = 5
t=224503 [st=413]  HTTP2_SESSION_UPDATE_RECV_WINDOW
                   --> delta = -211
                   --> window_size = 15728429
t=224503 [st=413]  HTTP2_STREAM_UPDATE_RECV_WINDOW
                   --> delta = 211
                   --> window_size = 15728640
t=224503 [st=413]  HTTP2_SESSION_RECV_DATA
                   --> fin = true
                   --> size = 0
                   --> stream_id = 5

--
--
Chromium Discussion mailing list: chromium...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-discuss

Bence Béky

unread,
Jul 13, 2017, 9:05:26 AM7/13/17
to dave....@gmail.com, Chromium-discuss, Chris Bentzel
Hi David,

According to the log, the response headers contain a header field with name (key) "/redeemvoucher" and value "".  RFC7230 Section 3.2 prescribes the format of header fields.  If you follow the definition of header-field, field-name, token, and tchar (see Appendix B for a list of all ABNF), it turns out that field names are not allowed to contain the character "/".  That is why Chrome is signalling an error upon receiving the response.

Cheers,

Bence

David Bell

unread,
Jul 13, 2017, 10:12:04 AM7/13/17
to Chromium-discuss, dave....@gmail.com, cben...@chromium.org
Hi, thanks for your replies, it's good to see something pointing to where the problem actually is.

I am still having problems figuring out exactly why this is a problem, or more to the point why now because this is supposedly the bit of nginx conf that is breaking it:

location /RedeemVoucher {
rewrite ^/RedeemVoucher/?$ /make_booking.php;
}

... and this is another example above that it's not complaining about:

location /AddCourse { 
rewrite ^/AddCourse/?$ /add_course.php;
}

As you can see, their format is the same, and this format is used on the other working sites. I'm not sure it matters but I did notice here that it contains capital letters, which the error does not.

So I thought maybe I should test with that block commented out. Still broken. Tried the logging link you gave me, no sign of that error but it still breaks the same in the following section anyway.

So I put it back in. Tested with logging. I can't find "HTTP2_SESSION_RECV_INVALID_HEADER" anywhere in it still, with the find tool too.

Bence, would you be able to advise on if that rewrite block is incorrect?

Thanks,

- David

David Bell

unread,
Jul 31, 2017, 10:11:00 AM7/31/17
to Chromium-discuss, dave....@gmail.com, cben...@chromium.org
Hi, I've updated to "Version 60.0.3112.78 (Official Build) (64-bit)", and the problem is still occurring. I've no idea what to do next because I can't recreate the error message here about the "redeemvoucher" bit.

I can't see how those two snippits of nginx conf differ enough to be the cause of a problem... Perhaps it's a red-herring and "redeemvoucher" happens to be the last/first thing it encounters before something else goes wrong?

David Bell

unread,
Aug 8, 2017, 9:57:32 AM8/8/17
to Chromium-discuss, dave....@gmail.com, cben...@chromium.org
SOLVED - I just wanted to leave a public record in case this comes up again for anyone else.

After hunting through Nginx config files, comparing, modifying, testing, testing, testing, I deleted the "/redeemvoucher" pseudo-directory bit, cleared every cache I could, still came back as "/redeemvoucher"->fault.

It was then that I opened our index.php to discover a header() redirect to "/redeemvoucher", but it was missing the "Location: " bit at the start, and so creating a faulty header. Put that in, and it worked straight away without even clearing caches.


Hope this helps someone else!
Reply all
Reply to author
Forward
0 new messages