>
Tech News

Chrome just decided to reject some HTTP responses without telling you

The first time I saw net::ERR_BLOCKED_BY_RESPONSE in Chrome’s DevTools, I assumed the network had dropped the request. The page looked loaded but a chunk of it was blank, and the address bar showed the right URL. The server was fine. My browser had quietly decided that one of the responses it received was not allowed to be used on the page I was looking at, and it threw the response away without giving me a useful explanation. That was the first time I realized modern browsers reject a lot more responses than they used to, and most of the rejections happen in silence.

If you have ever seen this error and felt confused, the confusion is justified. Chrome is enforcing security policies that did not exist five years ago, and it does so in a way that treats legitimate users and attackers identically. The request reached the server, the server answered, and your browser said “thanks, I will not use that.” For a non-developer, this looks like a glitch. For a developer, it usually looks like a server config problem. Both interpretations can be right, depending on which of several headers Chrome was enforcing. The reason I am writing this is to unpack what is actually happening, so the next time you see the error you can read it instead of guessing.

The basic mechanics

The request did reach the server. The server answered. Chrome decided the answer was not allowed to be used on the page that requested it. The decision is made at the policy layer between the response and the page, and Chrome’s default behavior when a policy fails is to silently drop the response. Sometimes the page just stalls. Sometimes only one embedded frame goes blank. Sometimes the error shows up as a full-page error, sometimes it sits as a quiet line in the console that you only see if you open DevTools.

The headers that usually drive this are CORS (Cross-Origin Resource Sharing), Content-Security-Policy, and X-Frame-Options. They are rules a site sets about which other pages, scripts, or frames are allowed to load its content. When one of those rules fails, Chrome prints ERR_BLOCKED_BY_RESPONSE and refuses to hand the response to the page. The crucial detail is that the network path worked. The headers Chrome received told it “this response is fine for origin X but not for origin Y,” and your page happened to be origin Y.

This is the part most explainers skip, and it is the part that matters most for debugging. If the network never reached the server, you would see a different error class (DNS resolution failure, connection refused, certificate error, that kind of thing). When you see ERR_BLOCKED_BY_RESPONSE, the network path is fine. The issue is at the policy layer between the response and your page, and the fix is either on your side (if you own the page that loads the resource) or on the resource’s side (if you own the server hosting it).

What changed to make this more common

Cross-origin resource sharing has been around for years, but the policies Chrome enforces have grown over time. Two big shifts happened in the last few years. First, the Spectre family of CPU side-channel attacks (a class of attacks where malicious code reads memory it should not be able to access by exploiting timing differences in CPU cache behavior) made the browser vendors tighten up on cross-origin memory sharing. Features like SharedArrayBuffer, which lets JavaScript do true multi-threading, used to be available by default. Now they are gated behind a stack of cross-origin isolation headers (COEP, COOP, and CORP), and a site that does not send those headers cannot use those features without breaking in newer browsers.

Second, content security policies got stricter. Sites that were built before CORS, COEP, and friends were standard are now showing this error as browsers tighten up. A site that worked fine in 2022 might break in 2026 simply because Chrome decided a particular cross-origin resource policy was required for a feature the page is trying to use. The site owner did not change anything. The browser did.

That is the structural reason this error is more common than it used to be. Browsers enforce more policies than they used to. Sites have not all updated their headers. The result is that a meaningful number of legitimate sites get rejected for reasons that look like bugs to the people using them.

Where the policy layer lives

The policy enforcement happens in the browser, not on the network. This is important because it means the response was received. If you open DevTools and look at the Network tab, you can see the response headers Chrome got back from the server. The relevant headers are usually Access-Control-Allow-Origin, Cross-Origin-Resource-Policy, Cross-Origin-Opener-Policy, and Cross-Origin-Embedder-Policy. If a header says “this response is fine for origin X” and your page is origin Y, Chrome will silently drop the response and the ERR_BLOCKED_BY_RESPONSE is what you see in the console.

There is also a less common case where Chrome tacks a suffix onto the error: ERR_BLOCKED_BY_RESPONSE.NotSameOrigin. The suffix means the issue is specifically about cross-origin isolation, usually one of the COEP/COOP/CORP headers. The fix is the same in principle (the server needs to send the right header for your origin) but the diagnosis is more specific.

If you are an end user, the headers themselves are usually not something you can change. They are set by the site owner. If you are a developer and you control the resource being loaded, you can update the server to send the right header. If you control the page doing the loading, you can sometimes work around the issue by changing how you load the resource (for example, fetching the resource yourself with fetch and then handing it to your page in a way that does not trigger the policy check).

What you can do about it as an end user

You are not powerless, even though the fix is usually on the server side. A few steps will resolve the majority of cases.

Try a private browsing window first. With most add-ons turned off and no cache loaded, Chrome will tell you whether the page works at all. If it works in private browsing, the problem is one of your installed extensions or a stale cached response in your normal profile. Most ad blockers and privacy extensions will block third-party resources aggressively, and they often cause this exact error.

Disable your installed add-ons one at a time. If private browsing fixed it, return to your normal window and turn each extension off individually until the error disappears. The last one you disabled is the culprit.

Wipe the cache and cookies from your normal profile. Go to Chrome Settings, open the Privacy and Security section, and choose Clear Browsing Data. Start with cached files and cookies only, never the saved passwords. Stale cached responses can fail header checks even after the live server has been updated, especially if a service worker is involved.

Drop your VPN or proxy connection for one reload. Some VPNs and corporate antivirus products inject their own headers or block patterns that Chrome treats as a policy violation. Disconnecting for one reload tells you if your network path is the cause.

Try a different network entirely. If nothing else worked and you are on a corporate or restricted network, a personal hotspot or a different Wi-Fi will tell you if a firewall is in the middle of the network path.

  • Incognito test. Tells you if extensions or cache are the cause.
  • Extensions one at a time. Identifies which extension is blocking the resource.
  • Clear cache and cookies. Fixes stale cached responses.
  • VPN off. Rules out your VPN or proxy.
  • Different network. Rules out firewall interference.
  • File a report. If nothing else worked, the site owner needs to fix the headers.

What you can do about it as a developer

If you control the resource being loaded, you can update the server to send the right header. The specific header depends on the use case. For an embeddable image, font, or script, Cross-Origin-Resource-Policy: cross-origin is usually what you want. For a page that needs cross-origin isolation, the Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy headers need to be set together, and any third-party resource you load also needs to send Cross-Origin-Resource-Policy: cross-origin or the isolation breaks.

If you control the page doing the loading and you cannot change the third-party server, the workaround is usually to fetch the resource server-side or via a CORS proxy and hand it to your page in a way that does not trigger the policy check. This adds operational complexity and a dependency on a proxy you now have to maintain, but it works.

The best long-term fix is to audit all the third-party resources your page loads and make sure the ones you depend on send the right headers. The audit is a one-time job and the fix is permanent. Future Chrome updates will only tighten policies further, not loosen them.

Trade-offs

Strict browser defaults are a trade-off. Chrome could be more permissive and show you the response with a warning. It is not, because the strict default is safer in aggregate. The cost is that legitimate sites break when their owners have not updated their headers, and the cost falls on the people least equipped to debug it. End users see a broken page and assume the network is the problem. The network is fine. The issue is somewhere between the response and the page. Most end users will never open DevTools, and most end users will never file a support ticket. The ones who do are a small minority, and the sites that listen to them are an even smaller minority. The cost is real.

The benefit is that real attacks (cross-origin data theft, side-channel leaks) are blocked before they happen. A permissive default would expose millions of users to vulnerabilities that the strict default prevents. The trade-off is correct, but the cost is real and it falls on the people who do not have the technical context to debug it.

For end users, the practical trade-off is between time spent debugging and time spent reporting. If you are a non-developer hitting this error on a site you care about, file a support ticket with the site owner. Reporting saves you debugging time and helps the site fix the underlying problem. If you are a developer, the trade-off is between setting up correct cross-origin headers now versus debugging errors across browsers later. Set up the headers now.

If you only do one thing from this article, open DevTools the next time you see this error and read the response headers in the Network tab. The header that Chrome rejected will tell you which policy was being enforced, and from there the fix is one of the steps above or a server-side change by the site owner.

Leave a comment