August 28, 2017 HTTPS, HTTP/2, Chrome

When migrating your site to a more performant HTTP/2 protocol, it may happen that Chrome will not load a page and will display This site can’t be reached with ERR_SPDY_PROTOCOL_ERROR instead. HTTP/2 is derived from the earlier SPDY protocol, that's probably why the error message doesn't mention HTTP/2 at all.

:-( This site can’t be reached ERR_SPDY_PROTOCOL_ERROR

One of the reasons why you may see the ERR_SPDY_PROTOCOL_ERROR message is an invalid HTTP header coming from the server. Chrome is a bit more strict when processing binary HTTP/2, can't handle a header with a space instead of a dash (e.g. Referrer Policy instead of Referrer-Policy), or a header with double colon (e.g. Content-Security-Policy:: ...), so check your headers are being sent correctly. Firefox ignores such invalid HTTP header and will just display the page.

Here's how to find the offending header. Go to chrome://net-internals/#events (the link is not clickable, but you can just copy and paste it), type your domain into the search box there (I'll use as, well, an example), then try loading your misbehaving site in a different tab. Go back to chrome://net-internals/#events and click the row with HTTP2_SESSION in Source Type column.

chrome://net-internals/#events HTTP2_SESSION Source Type

On the right side, you'll see an HTTP/2 protocol details, this is the important part:

                --> header_name = "referrer policy"
                --> header_value = "same-origin"
                --> description = "Could not parse Spdy Control Frame Header."
                --> error_code = "1 (PROTOCOL_ERROR)"
                --> stream_id = 3

See the line with HTTP2_SESSION_RECV_INVALID_HEADER? There's an invalid header just below it, in this case it's the referrer policy header, with space instead of dash. Header names in HTTP/2 must be converted to lowercase, so even if you send Referrer-Policy from your app, the browser sees referrer-policy. Or invalid referrer policy in this case.

You'll find a lot of interesting things about your browser internals in chrome://net-internals/. There are requests which are not even displayed in Developer Tools, like the ones coming from extensions. Go and check it out, might be handy next time you need to debug something. I've used it when researching Opera browser “VPN” or unencrypted “VPN” in UR browser.

Michal Špaček

I build web applications and I'm into web application security. I like to speak about secure development. My mission is to teach web developers how to build secure and fast web applications and why.

Public trainings

Come to my public trainings, everybody's welcome:

PHP application security
(December 11–12, 2018 Praha)

HTTPS for developers and admins
(December 13, 2018 Praha)