If you searched for ERR_SPDY_PROTOCOL_ERROR, you are chasing an error message that Chrome stopped printing years ago. The protocol it names, SPDY, was retired in 2016, and Chrome renamed the error itself in 2019. The failure behind it is still very much alive, though. It just goes by a different name now: ERR_HTTP2_PROTOCOL_ERROR.
This guide explains what the error actually is, why the old name still circulates, and how to fix it, whether you are a visitor who cannot load a page or the person who runs the server.
Quick answer:
ERR_SPDY_PROTOCOL_ERROR is the retired name of Chrome network error -337. Chrome renamed it to ERR_HTTP2_PROTOCOL_ERROR in Chrome 77 (September 2019), and dropped the SPDY protocol entirely back in Chrome 51 (May 2016). Despite living among SSL errors, it is not a certificate problem: the TLS handshake has already succeeded by the time it appears. It means Chrome received an HTTP/2 response it could not parse, usually because the server, a CDN, or a traffic-inspecting middlebox sent malformed frames or invalid headers. The fix belongs on the server or in the intercepting software, not in your certificate.
What ERR_SPDY_PROTOCOL_ERROR Means Today
Chrome identifies every network failure by a numeric code, and prints a text label built from that code. The code behind this error is -337. In Chromium’s canonical list of network errors, that entry now reads:
// There is an HTTP/2 protocol error.
NET_ERROR(HTTP2_PROTOCOL_ERROR, -337)
The label Chrome displays is generated directly from that entry, which is why current versions print ERR_HTTP2_PROTOCOL_ERROR and never ERR_SPDY_PROTOCOL_ERROR. The old string is not an alias and not a fallback. It simply no longer exists in the browser.
So if you are genuinely looking at the words ERR_SPDY_PROTOCOL_ERROR on screen, one of these is true:
- You are using a Chromium build older than version 77, which is now several years out of support and unsafe to browse with.
- You are inside an embedded browser that ships its own frozen Chromium engine, such as an old Electron desktop app, an outdated CEF-based application, or an Android System WebView that has not been updated.
- You are reading the error from an old log file, screenshot, or support article rather than from a live browser.
In every one of those cases the underlying condition is identical to the modern error, so the rest of this guide applies unchanged. Read ERR_SPDY_PROTOCOL_ERROR and ERR_HTTP2_PROTOCOL_ERROR as two names for the same event.
Why the SPDY Name Disappeared
SPDY, pronounced “speedy,” was an experimental protocol Google built to reduce page load latency. It multiplexed several requests over one connection, compressed headers, and let a server push resources before the browser asked for them. Those ideas worked well enough that the IETF used SPDY as the starting point for HTTP/2, published as a standard in May 2015.
Once the standard existed, keeping the prototype made no sense. On February 11, 2016, the Chromium team announced it was transitioning from SPDY to HTTP/2, and SPDY/3.1 support was removed in Chrome 51 in May 2016. No current browser or web server speaks SPDY. Any guide that tells you to “disable SPDY” or describes SPDY as something websites still run is describing the web of a decade ago.
The error label outlived the protocol by three more years because renaming a public error string breaks bookmarks, dashboards, and support scripts. Chrome finally made the change in version 77. Even now, the name survives inside Chromium’s own source tree: the HTTP/2 implementation still lives in a directory called net/spdy, and its central class is still named SpdySession. That internal vocabulary never reaches your screen, but it explains why the word keeps turning up in bug reports and stack traces.
This Is Not an SSL Certificate Error
This error is widely filed under SSL problems, and that placement causes real confusion, so it is worth being precise about the order of events.
HTTPS is built in layers. First the browser and server complete a TLS handshake: they agree on a protocol version and cipher suite, and the browser validates the server’s certificate. Only after that succeeds does the encrypted tunnel open, and only then does HTTP/2 start moving data through it.
ERR_HTTP2_PROTOCOL_ERROR happens at that second stage. Reaching it proves the handshake already worked and the certificate already validated. Replacing, renewing, or reinstalling the certificate therefore cannot resolve it, and a certificate scan will come back clean while the site stays broken.
Genuine certificate faults produce different codes, and it is worth learning to tell them apart at a glance:
- ERR_SSL_PROTOCOL_ERROR means the TLS handshake itself failed, so nothing encrypted was ever established.
- ERR_SSL_VERSION_OR_CIPHER_MISMATCH means the two sides share no TLS version or cipher suite they both accept.
- ERR_QUIC_PROTOCOL_ERROR is the direct equivalent of this error one protocol over, raised when the same class of framing fault occurs on an HTTP/3 connection.
If you want to rule the certificate out before going further, scan the domain with our free SSL Checker. A clean result confirms the problem sits above the TLS layer, exactly where this guide looks for it.
Save 10% on SSL Certificates when ordering from SSL Dragon today!
Fast issuance, strong encryption, 99.99% browser trust, dedicated support, and 25-day money-back guarantee. Coupon code: SAVE10
What Actually Causes ERR_HTTP2_PROTOCOL_ERROR
HTTP/2 is a binary protocol with strict rules. Chrome parses every incoming frame against those rules, and when something violates them badly enough that the connection can no longer be trusted, it stops and raises error -337. The specific triggers fall into a few groups.
Malformed response headers
This is the most common cause by a wide margin. Chrome validates every response header it receives and rejects the whole response if any of these is true:
- A header name contains an uppercase letter. HTTP/2 requires header names to be lowercase, so a server emitting Content-Type instead of content-type breaks the connection even though the same header is perfectly legal over HTTP/1.1.
- A header name is empty or contains a character that is not valid in a header name.
- A header value contains a control character, most often a stray newline, carriage return, or null byte injected by application code that builds headers from user input or from a database field.
- A pseudo-header follows a regular header. The entries beginning with a colon, such as :status, must come first in the block.
- The header block is too large. Chrome advertises a limit of 256 KB for a response header list and rejects anything beyond it.
The trap here is that HTTP/1.1 tolerates all of these. A site can run for years on HTTP/1.1 with a slightly malformed header and break the moment HTTP/2 is switched on.
Invalid or unexpected frames
Beneath the header rules, Chrome also rejects a connection when it receives an invalid control frame, a frame with bad padding, illegal data-frame flags, an invalid stream identifier, or a frame that arrives out of sequence. These point at a defective HTTP/2 implementation rather than at content: an old server build, a proxy that rewrites traffic incorrectly, or a load balancer whose HTTP/2 support is incomplete.
Traffic-inspecting software in the middle
Antivirus suites with HTTPS scanning, corporate TLS inspection appliances, and some VPN or filtering clients work by terminating your encrypted connection, examining the plaintext, and re-encrypting it. That makes them a full participant in the HTTP/2 conversation. If their implementation is weaker than the browser’s, they can hand Chrome frames it refuses to accept, and the site fails even though the real server is healthy.
This is the one cause that lives on the visitor’s machine, and it is the reason a page can break for a single person while working everywhere else.
Why Chrome does not just retry over HTTP/1.1
Chrome retries automatically on a small set of network errors where a retry is known to be safe, such as a failed HTTP/2 ping or a stream the server explicitly refused. Error -337 is deliberately not on that list. A protocol violation means Chrome can no longer trust what it is reading, so it tears the connection down and surfaces the failure instead of silently downgrading. That design choice is why you get a hard error page rather than a slow but working site.
How to Fix It as a Visitor
Work through these in order. The first two steps tell you whether the problem is yours at all, which saves time on the rest.
1. Check whether the site is broken for everyone
Open the same address on a different network, such as a phone on mobile data with Wi-Fi switched off. If it fails there too, the fault is on the server and no amount of local troubleshooting will help. Report it to the site owner and send them the section below.
If it loads elsewhere, something on your machine or network is interfering, and the remaining steps apply.
2. Test in an Incognito window
Incognito runs without most extensions and with a separate cookie jar, which separates two different suspects in one move.
- Click the three dots in the upper-right corner of Chrome.
- Select New Incognito Window, or press Ctrl+Shift+N on Windows and Linux, or Command+Shift+N on macOS.
- Load the failing address again.

If the page works in Incognito, the cause is an extension or an oversized cookie. Re-enable your extensions one at a time to find the culprit, and if none of them is responsible, clear the cookies for that specific site as described in step 4.
3. Turn off HTTPS scanning in your security software
If a security product is re-encrypting your traffic, its HTTP/2 handling is the likeliest culprit. Look in your antivirus or endpoint client for a setting named HTTPS scanning, SSL/TLS scanning, encrypted connection scanning, or web shield, and turn off that single feature.
Turn off only the interception component. Do not uninstall your antivirus or disable its real-time protection to test a web page, since that removes protection that has nothing to do with the error. If switching off HTTPS scanning fixes the site, update the security product to its current version and turn the feature back on. Vendors fix these HTTP/2 defects regularly, and leaving inspection off permanently is a downgrade you do not need to accept.
On a managed corporate laptop these settings are usually locked. In that case the TLS inspection appliance on the company network is the thing to report, and your IT team has to make the change.
4. Clear the cookies for that one site
This step is worth doing only for the specific reason that a very large cookie inflates every request header block your browser sends. Once that block passes what the server or an intermediary accepts, that side rejects the request instead of answering it, usually by resetting the HTTP/2 stream, and Chrome reports most stream resets as this error. Clearing cookies for the affected domain shrinks the header block immediately.
- Open the three-dot menu and go to Delete browsing data.
- Choose All time as the time range and tick Cookies and other site data.
- Click Delete data.

To avoid signing out of every site at once, open the padlock or tune icon to the left of the address bar, choose the site data option, and delete the data for that single domain instead. Note that clearing cached images and files is a different checkbox and does nothing for this error, for reasons covered further down.
5. Flush Chrome’s socket pools
Chrome reuses one HTTP/2 connection for many requests, and will even route several hostnames served by the same certificate down a single connection. When that shared connection enters a bad state, every site on it fails until Chrome opens a new one. Forcing that to happen takes a moment.
Type this into the address bar and press Enter:
chrome://net-internals/#sockets
Click Flush socket pools, then reload the page. This is the genuine socket-flushing control in Chrome, and it still ships in current versions. Older guides send you to the net-internals events viewer for this, which was removed years ago, or to the net-export page, which does not touch sockets at all.
6. Update Chrome
An up-to-date browser is worth having regardless, and if you are one of the rare people literally seeing the string ERR_SPDY_PROTOCOL_ERROR, updating is the entire fix, because only builds older than Chrome 77 print that name.
- Click the three dots in the upper-right corner.
- Select Help, then About Google Chrome.

Chrome checks for updates on that screen and installs anything it finds. Restart the browser when it asks.

If Chrome is already current, the browser is not the problem and the fault lies with the server or with software intercepting your traffic.
How to Fix It as a Site Owner
When visitors report this error, your job is to find which rule your responses break. Guesswork is slow here, and the tooling is good, so measure first.
1. Confirm HTTP/2 is the variable
Request the same URL twice, forcing a different protocol each time:
curl -sI --http1.1 https://example.com/
curl -sI --http2 https://example.com/
If the HTTP/1.1 request returns headers normally and the HTTP/2 request fails or returns nothing, you have confirmed the problem is in the HTTP/2 layer and can ignore everything below it, including the certificate.
2. Read the exact reason from a NetLog
Chrome can record precisely why it rejected the connection, including the offending header name and value. This is the fastest path to a fix, and it is what the net-export page is genuinely for.
In a Chrome window, type this into the address bar and press Enter:
chrome://net-export/
- Click Start Logging to Disk and choose where to save the file.
- In another tab, load the URL that fails.
- Return to the net-export tab and click Stop Logging.

Open the saved file in the NetLog viewer and look for events named HTTP2_SESSION_RECV_INVALID_HEADER. Each one carries the header name, the header value, and a plain-language reason drawn from a fixed set: “Header name must not be empty.”, “Invalid character in header name.”, “Upper case characters in header name.”, “Pseudo header must not follow regular headers.”, “Header list too large.”, or “Invalid character 0x0A in header value.”, where that last one names the exact offending byte. Those reasons correspond directly to the causes listed above, so the event tells you precisely what to correct.
Capturing the log is a read-only operation. It records what happens, and starting or stopping it changes nothing about your connection.
3. Correct the headers your application sends
Most fixes land in application code rather than in server configuration. Check anywhere your code sets a header by hand, and audit the plugins or middleware that add their own.
- Send header names in lowercase only.
- Strip carriage returns, newlines, and other control characters from any header value built from user input, a database column, or a file name.
- Watch for values holding non-ASCII text, such as a file name in a Content-Disposition header. Encode those rather than passing them through raw.
- Remove duplicate or empty headers added by overlapping layers, for example a caching plugin and the web server both setting the same one.
To inspect frames at the protocol level, the nghttp client prints every frame Chrome would see. It comes from the nghttp2 project and is packaged separately from curl, so it is usually not present until you install it:
nghttp -nv https://example.com/
4. Keep the header block within limits
If the error follows a login, or appears only for signed-in users, suspect header size. Session data stored in cookies grows quietly, and authentication systems that write large tokens are a frequent source. Check the total size of the cookies your site sets, move bulky state into server-side storage keyed by a short identifier, and confirm your server and CDN limits agree, since an intermediary with a smaller limit than your origin will fail the request on its own.
5. Update the software that terminates HTTP/2
HTTP/2 is terminated by whatever answers TLS first, which may be your web server, a reverse proxy, a load balancer, or a CDN edge. Identify which one it is and update it, because HTTP/2 framing defects are a well-worn category of bug and most have long been fixed upstream. If your site sits behind a CDN, reproduce the error against the origin directly before changing anything, so you know which side is at fault.
6. Disable HTTP/2 as a temporary confirmation
Turning HTTP/2 off in your server or CDN settings makes the error disappear at once, because every client falls back to HTTP/1.1. Treat that strictly as a diagnostic that confirms where the fault lies, not as a resolution. Running on HTTP/1.1 costs real performance, so switch HTTP/2 back on once the malformed response is fixed.
What Does Not Fix This Error
Troubleshooting guides for this error tend to recycle a generic checklist written for certificate warnings. Those steps are harmless, but they cannot affect a protocol framing failure, and following them wastes the time you need for the checks that matter. Here is why each one misses.
- Clearing cached images and files. The cache stores content Chrome already received successfully. This error means the current response never parsed, so there is no bad cached copy to remove. Cookies are the exception, and only because they change the size of what gets sent, which is why they have their own step above.
- Correcting your computer’s clock. A wrong system time invalidates certificate date checks and produces errors such as ERR_CERT_DATE_INVALID. Those fire during the handshake. By the time you see a protocol error, certificate validation has already passed.
- Flushing DNS or renewing your IP address. DNS translates a name into an address. You already reached the right server and it already answered, so resolution plainly worked. These commands are safe and occasionally useful if you suspect you are being routed to a stale endpoint, but they do not repair a response Chrome could not parse.
- Resetting the Windows SSL state or emptying the SSL slate. That clears cached client certificates and TLS session state, which again belongs to the handshake stage that already succeeded.
- Starting and stopping a net-export log to “refresh network activity.” The net-export page only writes a diagnostic file. It does not reset connections, flush sockets, or alter traffic in any way. It is genuinely useful, but as the measurement in step 2 for site owners, not as a fix.
- Reinstalling or reissuing the SSL certificate. The certificate was accepted before HTTP/2 ever started. Replacing it changes nothing about how your server frames its responses.
For reference, the DNS commands that circulate with this error are these, run in an elevated Command Prompt on Windows:
ipconfig /flushdns
ipconfig /release
ipconfig /renew
They clear cached DNS records and request a fresh address from your router. Nothing about that sequence changes how a server frames an HTTP/2 response, so reach for them only when you have an actual name-resolution problem.
Frequently Asked Questions
Yes. Both are Chrome network error -337. Chrome used the SPDY name until version 76 and has used the HTTP/2 name from version 77 onward, released in September 2019. The numeric code, the meaning, and the fixes are identical. Only the label changed.
No. Chrome removed SPDY support in version 51 in May 2016, and the other browsers and the major web servers dropped it in the same period. Every connection that once used SPDY now uses HTTP/2 or HTTP/3. Advice telling you to enable, disable, or configure SPDY is obsolete.
No. HTTP/2 runs inside the encrypted tunnel, so the TLS handshake and certificate validation both finished successfully before this error could occur. Renewing or reinstalling the certificate will not help. If you want to confirm the certificate is healthy, run the domain through the SSL Checker, then move on to the HTTP/2 checks in this guide.
The ERR_ labels are Chromium’s, so this failure surfaces in Chrome, Microsoft Edge, Brave, Opera, and Vivaldi, as well as in applications built on Electron or CEF and in Android System WebView. Current builds of all of them print ERR_HTTP2_PROTOCOL_ERROR; only builds predating Chrome 77 print the SPDY name. Firefox does not use Chromium’s labels at all. It carries its own codes for the same conditions, such as NS_ERROR_NET_HTTP2_SENT_GOAWAY, and reports them through its generic connection-failure pages. The same broken server can therefore produce quite different wording from one browser to the next.
Usually it is the website or its CDN, and a visitor can do nothing but report it. The one exception is traffic-inspecting software on your own machine or network, such as antivirus HTTPS scanning or a corporate TLS inspection appliance. Testing the same page on a different network separates the two cases in under a minute.
Only as a temporary measure. Disabling HTTP/2 forces every visitor onto HTTP/1.1, which hides the symptom while giving up the multiplexing and header compression that make pages load faster. Use it to confirm the diagnosis, fix the malformed response the NetLog identifies, then re-enable HTTP/2.
Because the offending header is generated by that page’s code. A download route setting a Content-Disposition header from a file name with an accented character, or an endpoint echoing user input into a header, will break while every static page on the same server keeps working. Capture a NetLog while loading the failing URL and the invalid header event will name the exact header.
Signing in sets session cookies, and those cookies travel in the header block of every subsequent request. If they grow large enough, the header block exceeds what your server or CDN accepts, and that side resets the HTTP/2 stream instead of answering it, which Chrome reports as this error. Clearing cookies for that site restores access immediately, and the durable fix is to shrink what the site stores in them.
For more SSL error troubleshooting, check our detailed tutorials about fixing different SSL errors.
Save 10% on SSL Certificates when ordering from SSL Dragon today!
Fast issuance, strong encryption, 99.99% browser trust, dedicated support, and 25-day money-back guarantee. Coupon code: SAVE10

