bg-tutorials

How to Fix ERR_QUIC_PROTOCOL_ERROR in Chrome

ERR_QUIC_PROTOCOL_ERROR is a Google Chrome error that appears when a connection over QUIC, the transport protocol behind HTTP/3, fails. The page simply refuses to load, often on one site while everything else works, and often on one network while the same site loads fine on another.

What makes this error worth understanding is that you are not supposed to see it. Chrome is built to fall back to the older TCP transport whenever QUIC misbehaves, and that fallback normally happens silently. When the error reaches your screen, the fallback did not happen, and the reason it did not happen tells you where the problem is.

Quick answer:

ERR_QUIC_PROTOCOL_ERROR (Chrome network error -356) means Chrome’s connection over QUIC, the transport underneath HTTP/3, failed and could not be retried over ordinary TCP. It is not a certificate problem, and no certificate needs to be reissued.

The most common cause is a firewall, VPN, or security appliance that filters UDP port 443, which QUIC needs, while leaving TCP port 443 open. To confirm it, load the same page on a different network such as a phone hotspot: if it works there, the original network is blocking QUIC.

Site owners should check the HTTP/3 setting on their CDN or web server and make sure UDP 443 is open. Disabling QUIC in Chrome at chrome://flags/#enable-quic does stop the error, but it turns HTTP/3 off for every site you visit, so use it to confirm the diagnosis and then switch it back on.

What ERR_QUIC_PROTOCOL_ERROR actually means

Chrome keeps a numbered list of internal network errors, and this one is -356 QUIC_PROTOCOL_ERROR. Its description in Chromium’s net_error_list.h is deliberately broad: “There is a QUIC protocol error.” It covers any situation where the QUIC connection carrying your request broke in a way Chrome could not recover from.

Two things follow from that, and both save time.

First, this is a transport failure, not a certificate failure. The error says nothing about whether a certificate is expired, self-signed, or issued to the wrong name. If you are a site owner who landed here from a visitor report, do not reissue anything. You can confirm that with a scan: run the domain through our free SSL Checker, which reports expiry, the chain, and configuration problems. On a genuine QUIC transport failure it comes back clean, and that clean result is itself a useful data point.

Second, the error is Chrome-specific. Chromium-based browsers such as Edge, Brave, Opera, and Vivaldi show the same code because they share the same network stack. Firefox and Safari also support HTTP/3 but report their own failures differently, so a page that throws ERR_QUIC_PROTOCOL_ERROR in Chrome may load normally in Safari. That is not proof the site is fine, only that the other browser took a different transport.

Why Chrome shows the error instead of falling back to TCP

This is the part most troubleshooting guides skip, and it is the part that makes the rest of the fixes make sense.

Chrome does not use HTTP/3 because you asked it to. It discovers that a site supports HTTP/3 (usually from an Alt-Svc response header or an HTTPS DNS record), files that away as an “alternative service,” and uses it on later requests. Crucially, when a request over that alternative service fails with a QUIC protocol error, Chrome’s default behaviour is to retry the request with alternative services switched off, which lands it back on TCP with ordinary TLS. You never notice. The page just loads.

The logic lives in Chromium’s HttpNetworkTransaction::HandleIOError function. Its gate for QUIC protocol errors reads as follows:

case RetryReason::kQuicProtocolError:
  if (HasExceededMaxRetries() || GetResponseHeaders() != nullptr ||
      !stream_->GetAlternativeService(&retried_alternative_service_)) {
    // If the response headers have already been received and passed up
    // then the request can not be retried. Also, if there was no
    // alternative service used for this request, then there is no
    // alternative service to be disabled.
    return error;
  }

Reading it plainly: Chrome returns the error to you, instead of quietly retrying, only when one of three things is true.

  1. The retry budget is used up. Chrome allows two retry attempts. Exhausting them means every attempt failed, which is the signature of a network path that mangles or drops all QUIC traffic rather than an occasional glitch. This is the case that points at a firewall.
  2. Response headers had already arrived. The connection broke partway through the response, after Chrome had already handed the headers up the stack. At that point the request cannot safely be replayed, so there is nothing to fall back to. This is the case that points at an unstable connection or a server that dropped the stream mid-transfer.
  3. No alternative service was in play. If the failing request was not running through an alternative service, there is nothing for Chrome to disable, so there is no retry to make. In practice this shows up when QUIC is involved through a configured QUIC proxy rather than through normal Alt-Svc discovery.

So a visible ERR_QUIC_PROTOCOL_ERROR is not random. It means QUIC failed and the automatic escape route was unavailable. In the overwhelming majority of real cases that is the first condition, which is why the network, not the browser, is the right place to start looking.

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

A detailed image of a dragon in flight

What the QUIC protocol is

QUIC is a transport protocol originally developed at Google and standardised by the IETF as RFC 9000 in May 2021. HTTP/3, the version of HTTP that runs on top of it, followed as RFC 9114 in June 2022. It is a settled standard, not an experiment: HTTP/3 is supported by every current major browser and by a large share of the busiest sites on the web.

The single most important thing to know about it for troubleshooting purposes is that QUIC runs over UDP, not TCP. Standard HTTPS uses TCP port 443. QUIC uses UDP port 443. They are different ports as far as any firewall is concerned, and that distinction is the root of most of the errors in this article.

The rest of what QUIC brings:

  • Lower connection latency: QUIC combines the transport handshake and the encryption setup into a single exchange, so a connection is ready in fewer round trips.
  • No head-of-line blocking: TCP delivers bytes strictly in order, so one lost packet stalls everything behind it. QUIC carries multiple independent streams in one connection, and a loss on one stream does not hold up the others.
  • Encryption is mandatory: TLS 1.3 is built into the protocol rather than layered on top of it, as specified in RFC 9001. There is no unencrypted QUIC.
  • Connection migration: connections are identified by a connection ID rather than by an IP address and port, so moving from mobile data to Wi-Fi does not break an in-flight transfer.

That last property, along with the fact that QUIC encrypts far more of its own metadata than TCP plus TLS does, is exactly why some network operators would rather it did not run on their networks at all.

What causes ERR_QUIC_PROTOCOL_ERROR

1. A firewall or security appliance filtering UDP port 443

This is the most common cause by a wide margin, and it is usually deliberate rather than accidental.

Firewalls that perform deep packet inspection can decrypt and examine TLS over TCP using a forward-proxy configuration. They cannot do the same to QUIC. So the standard vendor recommendation is to block QUIC outright, which makes browsers fall back to TCP, where inspection works. Palo Alto Networks documents exactly this approach in its Block QUIC protocol article, and advises blocking both the QUIC application signature and UDP ports 80 and 443, because blocking the signature alone can be evaded when the traffic is classified as unknown UDP. Fortinet publishes a matching Blocking QUIC manually procedure. Older FortiOS releases blocked QUIC by default in the Application Control profile; that default was removed in FortiOS 7.2.4 once flow inspection gained full HTTP/3 support, but plenty of deployments still carry the block from an inherited profile or a policy decision.

The result is a network where TCP 443 is open and UDP 443 is not. Chrome learns from an Alt-Svc header that a site speaks HTTP/3, tries it, gets nothing back, retries, gets nothing back, exhausts its budget, and surfaces the error. This is why the problem clusters on corporate, school, hotel, and guest Wi-Fi networks, and why the same site loads instantly over a phone hotspot.

2. A VPN, antivirus, or security suite on your own machine

Endpoint security products do a local version of the same thing. An antivirus “web shield” or HTTPS scanning module intercepts browser traffic to inspect it, and most of them only understand TCP. QUIC either gets dropped or gets forwarded in a way that corrupts it. VPN clients cause the error for a related reason: some tunnel TCP reliably but handle UDP poorly, and an unstable UDP path produces exactly the repeated failures that use up Chrome’s retry budget.

3. A problem on the site’s server or CDN

The server side is a genuine cause, and it is the one visitors cannot do anything about. A site can advertise HTTP/3 through an Alt-Svc header while its HTTP/3 endpoint is unreachable, misconfigured, or served by a component that closes streams incorrectly. A frequent version of this is a server firewall that allows TCP 443 but was never opened for UDP 443, so the site tells every browser “HTTP/3 is available here” and then never answers on it.

A connection that fails partway through a large response falls into this group too. That is the second condition from the section above: once headers have been delivered, Chrome cannot replay the request, so the error surfaces instead of a silent retry.

4. Proxy configuration

Conventional HTTP proxies are a TCP mechanism. When a proxy is configured, correctly or otherwise, the interaction between the proxy settings and QUIC can produce this error, particularly when a proxy auto-configuration script points at a server that no longer exists. Stale proxy settings left behind by an uninstalled VPN or corporate agent are a common source.

5. Browser extensions

Extensions that intercept or rewrite requests, such as ad blockers, privacy tools, and proxy switchers, can interfere with how Chrome handles connections. This is a real but comparatively rare cause, which is why it belongs below the network checks rather than above them.

6. An unreliable UDP path

Some home routers and carrier-grade NAT devices handle UDP poorly, expiring UDP state aggressively or fragmenting packets that TCP would have handled. Congested or weak Wi-Fi produces the same effect. The symptom is intermittence: the error appears on large pages or long downloads and disappears on a reload.

Diagnose it before changing any settings

Four checks will place the fault on the network, the browser, or the site, and they take a couple of minutes.

Check 1. One site or every site?

If the error hits many unrelated sites, the problem is your network or your machine. If it hits exactly one site while everything else works, the problem is that site’s HTTP/3 configuration, and there is nothing to fix on your end beyond reporting it.

Check 2. Compare two networks

Load the failing page over a phone hotspot or any network outside the one you are on. If it loads there and not on the original network, you have confirmed the dominant cause: something on that network is filtering UDP 443. No amount of browser configuration will change that, and the fix belongs to whoever runs the network.

Check 3. Look at the Protocol column in DevTools

Open Chrome DevTools with F12, go to the Network panel, right-click the column headers of the request table, and enable Protocol. Reload the page. The column shows the transport used for each request: h3 for HTTP/3, h2 for HTTP/2, and http/1.1 for the oldest. If you never see h3 anywhere, on any site, QUIC is not getting out of your network at all.

Check 4. Test a known HTTP/3 endpoint

Cloudflare runs cloudflare-quic.com, a page that reports whether your connection reached it over HTTP/3. It is a clean control test: the site is known to work, so a result other than HTTP/3 points at your path rather than at the destination.

If you need hard evidence, capture a net log

Older guides send you to chrome://net-internals/#quic. That page no longer exists. The QUIC view was removed from net-internals, which today only keeps a handful of views such as DNS, sockets, and proxy. The current tool is chrome://net-export: start a recording, reproduce the error, stop the recording, and open the resulting JSON file in the NetLog Viewer. This is what to attach when you escalate to a network team or a hosting provider, because it shows the failing connection attempts directly.

How to fix ERR_QUIC_PROTOCOL_ERROR as a visitor

Work through these in order. They are arranged by how often they turn out to be the answer, not by how easy they are.

1. Deal with the network filtering UDP 443

If the two-network comparison above pointed at your network, this is your fix. On a network you control, check whether the router or firewall has a QUIC or HTTP/3 blocking rule and allow outbound UDP 443. On a corporate or school network, you cannot change this yourself, and you should not try to route around it: the block is usually a deliberate security control that lets the organisation inspect encrypted traffic. Ask the network team whether QUIC is blocked. If it is, and it is going to stay blocked, disabling QUIC in Chrome (step 5) is the appropriate local workaround on that machine.

2. Turn off VPN and antivirus HTTPS scanning temporarily

Disconnect any VPN and reload the page. If that fixes it, the VPN’s UDP handling is the cause, and the vendor’s support channel is the right place to take it.

Next, look for an HTTPS scanning, web shield, or SSL inspection feature in your antivirus or internet security suite and switch it off briefly. If the error clears, add the affected site to that product’s exclusion list rather than leaving the whole feature disabled.

3. Check your proxy settings

Confirm that no stale proxy is configured. If you do use a proxy, verify the address and port are still correct.

On Windows:

  1. Open the Start menu and select Settings, the gear icon.
  2. Select Network & Internet.
  3. Select Proxy.
  4. Under Automatic proxy setup, leave Automatically detect settings on unless your network requires otherwise, and make sure Use setup script is off if you were never given a script address. Under Manual proxy setup, Use a proxy server should be off unless your organisation told you to enable it. A leftover entry here, typically from an uninstalled VPN or a network you no longer use, is the version of this problem worth finding.
  5. Close Settings and restart Chrome.
Windows Settings showing the Network and Internet section
Windows Network and Internet settings with the Proxy entry selected
Windows proxy settings with the Use a proxy server toggle turned off

On macOS: open System Settings, select Network, choose your active connection, click Details, and open Proxies. Every protocol listed there should be off unless you deliberately configured one. To check the HTTPS proxy for Wi-Fi from Terminal:

networksetup -getsecurewebproxy "Wi-Fi"

On Linux: Chrome follows the desktop environment’s proxy settings and the shell’s proxy environment variables. Check the latter with:

env | grep -i proxy

Any unexpected entry pointing at a host you do not recognise should be removed from your shell profile.

4. Rule out browser extensions

The fastest test is an Incognito window, since extensions are disabled there by default. If the page loads in Incognito, an extension is responsible, and you can narrow it down:

  1. Click the three vertical dots in the upper-right corner of Chrome.
  2. Select Extensions, then Manage Extensions.
  3. Toggle every extension off.
  4. Reload the failing page. If it works, re-enable the extensions one at a time, reloading after each, until the error returns. The last one you switched on is causing it.
Chrome menu showing the Extensions and Manage Extensions options
Chrome extensions page with a toggle switch to disable an extension

5. Disable QUIC in Chrome, as a diagnostic

Turning QUIC off makes Chrome use TCP for everything, so the error stops. Treat that as a test result, not as the repair. It disables HTTP/3 for every site you visit, giving up the performance that HTTP/3 provides everywhere else in order to work around one broken path. It is also precisely the outcome a QUIC-blocking middlebox is designed to produce, so leaving it off permanently means the network got what it wanted and you never found out why.

Paste this into the address bar to jump straight to the flag:

chrome://flags/#enable-quic
  1. Press Enter. Chrome opens the experiments page with Experimental QUIC protocol highlighted.
  2. Set the dropdown next to it to Disabled.
  3. Click Relaunch at the bottom of the page.
  4. Reload the failing page. If it works now, QUIC was the problem, and the real cause is somewhere in the list above.
  5. Set the flag back to Default once you have your answer, unless you are on a network that blocks QUIC permanently and you have accepted that trade.
Chrome experiments page showing the Experimental QUIC protocol flag set to Disabled

One reassurance about this step: Chrome flags are usually removed after a few releases, but this one is not going anywhere. Chromium’s flag metadata gives enable-quic an expiry of -1, never, with the comment that it “is used by network administrators to debug network issues related to QUIC. It must not be removed.”

How to fix it on your own site

If visitors are reporting ERR_QUIC_PROTOCOL_ERROR on your site while it loads fine for you, your HTTP/3 endpoint is advertised but not dependable. Advertising HTTP/3 and then failing on it is worse than not offering it, because every Chrome visitor tries the broken path first.

Check whether you are actually serving HTTP/3

Start with the advertisement. A site that offers HTTP/3 sends an Alt-Svc response header:

curl -sI https://example.com | grep -i alt-svc

A working site returns something like this, which tells browsers that HTTP/3 is available on UDP port 443 and that they may remember it for 24 hours:

alt-svc: h3=":443"; ma=86400

Then check that the advertised endpoint answers. If your curl build includes HTTP/3 support, force it:

curl --http3 -sI https://example.com

Not every curl binary can do this. Run the following and look for HTTP3 in the output; if it is absent, your curl was not built with HTTP/3 support and you should test in a browser instead, using the DevTools Protocol column described earlier.

curl -V | grep -i features

An Alt-Svc header that promises h3 while the HTTP/3 request fails is the exact configuration that generates this error for your visitors.

Open UDP port 443

This is the single most common server-side mistake. HTTP/3 gets enabled in the web server, but the host firewall and the cloud security group were only ever opened for TCP 443. On a Linux server using UFW:

sudo ufw allow 443/udp

Then open UDP 443 in your cloud provider’s security group or network ACL as well. A local firewall rule alone will not help if the traffic is dropped before it reaches the machine.

If you use Cloudflare

HTTP/3 is a single toggle. In the Cloudflare dashboard, go to Speed, then Settings, then Protocol Optimization, and set HTTP/3 (with QUIC) as required. It is available on all plans and requires a certificate at Cloudflare’s edge.

One detail that resolves a lot of confusion: this setting only governs the connection between the visitor and Cloudflare. As Cloudflare’s HTTP/3 documentation states, HTTP/3 to the origin is not supported. So your origin server does not need HTTP/3 at all when you sit behind Cloudflare, and turning HTTP/3 on at the origin will not affect what visitors experience. If visitors report this error on a Cloudflare-proxied site, toggling HTTP/3 off is a legitimate short-term mitigation while you investigate.

If you run the web server yourself

  • nginx has supported HTTP/3 since version 1.25.0, through the ngx_http_v3_module, which must be compiled in with the build option shown in nginx’s documentation. Confirm your build includes it before assuming the configuration is at fault. The http2 on; directive used in the sample below arrived separately, in nginx 1.25.1.
  • LiteSpeed and OpenLiteSpeed have shipped HTTP/3 enabled by default since version 6.0.2, so the usual cause of failure there is a closed UDP 443, not a missing setting.
  • Caddy has enabled HTTP/3 by default since version 2.6. Again, check UDP 443 first.
  • Apache HTTP Server does not support HTTP/3. If you need it, put a reverse proxy that does in front of it, or use a CDN.

A minimal nginx configuration serving HTTP/3 alongside HTTP/2 on the same port looks like this:

server {
    listen 443 quic reuseport;
    listen 443 ssl;
    http2 on;

    ssl_certificate     /etc/ssl/certs/example.com.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;

    add_header Alt-Svc 'h3=":443"; ma=86400' always;
}

The reuseport parameter belongs on only one listen directive per port across your whole configuration, so if another server block already sets it, leave it out here. Test the configuration before reloading:

sudo nginx -t && sudo systemctl reload nginx

If you cannot fix it quickly, stop advertising HTTP/3

Removing the Alt-Svc header, or turning HTTP/3 off at your CDN, makes browsers stay on HTTP/2 over TCP. Visitors lose a little performance and get a working site, which is the better trade while you sort out the underlying problem.

Chrome has several QUIC-related error codes that look similar and mean different things. Getting the right one saves you from fixing the wrong problem, and only one of them is about certificates.

ErrorCodeWhat it meansCertificate related?
ERR_QUIC_PROTOCOL_ERROR-356The QUIC connection failed and could not be retried over TCP.No
ERR_QUIC_HANDSHAKE_FAILED-358The QUIC handshake never completed, so the server read no requests. Usually UDP 443 is unreachable.No
ERR_QUIC_CERT_ROOT_NOT_KNOWN-380The certificate presented on the QUIC connection does not chain to a known root.Yes
ERR_QUIC_GOAWAY_REQUEST_CAN_BE_RETRIED-381The server sent a GOAWAY frame, so the request was not processed and is safe to retry.No

The one to separate from the rest is -380 ERR_QUIC_CERT_ROOT_NOT_KNOWN. That error genuinely is a certificate problem, and it means the chain served on the QUIC connection does not lead back to a trusted root, most often because an intermediate certificate is missing from the server configuration. The remedy is the same as for NET::ERR_CERT_AUTHORITY_INVALID: install the full chain, then verify it with our SSL Checker.

There is also a direct HTTP/2 counterpart to this error. Chrome reports it as ERR_HTTP2_PROTOCOL_ERROR, still widely known by its retired name ERR_SPDY_PROTOCOL_ERROR, when an HTTP/2 connection fails in an equivalent way, and it is worth checking if disabling QUIC did not help, because that would mean the trouble is not specific to HTTP/3 at all. For failures in the TLS layer rather than the transport, see ERR_SSL_PROTOCOL_ERROR and ERR_SSL_VERSION_OR_CIPHER_MISMATCH.

Frequently Asked Questions

Is ERR_QUIC_PROTOCOL_ERROR an SSL certificate problem?

No. It is a transport-level failure in QUIC, the protocol underneath HTTP/3, and it carries no information about certificate validity. Reissuing, reinstalling, or replacing a certificate will not resolve it. The QUIC error that does involve certificates is ERR_QUIC_CERT_ROOT_NOT_KNOWN (-380), which means the served chain does not reach a trusted root.

Should I just leave QUIC disabled in Chrome?

Only if you are on a network that blocks QUIC and will keep blocking it. The flag is global, so it removes HTTP/3 from every site you visit, not just the one that failed. Use it to confirm that QUIC is the cause, then set it back to Default and fix the actual problem. The exception is a managed corporate machine on a network where QUIC is blocked by policy, where disabling it locally is the sensible arrangement.

Why does the site work on my phone but not on the office Wi-Fi?

Because the office network is almost certainly filtering UDP port 443. Corporate firewalls block QUIC so that traffic falls back to TCP, where the firewall can decrypt and inspect it. Your mobile connection does not do that, so QUIC works. This is the most common explanation for an error that follows you between networks.

Why do I get this error when Chrome is supposed to fall back to TCP?

Chrome does fall back, and normally you never see a QUIC failure at all. It skips the fallback in three situations: it has already used its two retry attempts, the response headers had already been delivered so the request cannot be replayed, or the request was not using an alternative service that could be switched off. Reaching the retry limit is the usual case, and it indicates a network path that fails every QUIC attempt rather than an intermittent fault.

Is chrome://net-internals/#quic still available?

No. The QUIC view was removed from net-internals, and only a few views such as DNS, sockets, and proxy remain. For QUIC diagnostics, use the DevTools Network panel with the Protocol column enabled for a quick check, and chrome://net-export with the NetLog Viewer when you need a detailed capture to share.

How do I tell whether my own site serves HTTP/3?

Check for an Alt-Svc response header containing h3, which is how a site advertises HTTP/3, then confirm the advertised endpoint actually answers. Browsers only try HTTP/3 after seeing that advertisement, so a site that sends it without serving working HTTP/3 causes this error for Chrome visitors while appearing healthy in any test that uses TCP.

Does this error affect Firefox and Safari too?

The error string is Chrome’s, and Chromium-based browsers such as Edge, Brave, Opera, and Vivaldi share it. Firefox and Safari also support HTTP/3 and can hit the same underlying network conditions, but they report the failure differently and may retry over TCP where Chrome did not. A page loading in Safari but not in Chrome does not clear the site of an HTTP/3 problem.

Can clearing the browser cache fix it?

Rarely, and only indirectly. Chrome caches which sites support HTTP/3, so clearing browsing data discards that list and makes Chrome rediscover it. That helps if the site changed its configuration recently and Chrome is acting on a stale entry. It does nothing about a firewall filtering UDP 443, which is the far more likely cause.

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

A detailed image of a dragon in flight
Written by

I've been writing for SSL Dragon for over 10 years, focusing entirely on SSL certificates and digital security. My job is to take complex cybersecurity topics and strip away the jargon, making sure you get the clear, practical information you need to keep your website safe.