After you add Cross-Origin-Embedder-Policy: require-corp to a page, several third-party images, a font from a CDN and an analytics iframe stop loading. Explain why, and walk through the options for restoring each one.
answer
- embedding flips to consent-required
- two ways to prove consent
- frames are not covered by CORP
- credentialless drops cookies instead
- report-only before enforcing
basics
~20 srequire-corp blocks every cross-origin subresource that has not opted in. Restore each by getting Cross-Origin-Resource-Policy: cross-origin from the provider, refetching in CORS mode, switching to COEP: credentialless, or self-hosting. Framed documents must send their own COEP header.
solid answer
~40 s`require-corp` flips embedding from permitted-by-default to consent-required: any cross-origin subresource that neither carries `Cross-Origin-Resource-Policy` nor is fetched in CORS mode with valid CORS headers is blocked outright. For the images, the cheapest fixes are adding `crossorigin="anonymous"` if the CDN already sends `Access-Control-Allow-Origin`, or asking the provider for `Cross-Origin-Resource-Policy: cross-origin`. Fonts are the same story, and font files are frequently already CORS-enabled because CSS font loading requires it. The iframe is the hard one — a framed document must send its own COEP header, which a third-party analytics vendor almost certainly will not; Chromium's `credentialless` iframe attribute is a partial escape hatch. If nothing else works, proxy or self-host the asset so it stops being cross-origin. Always stage this with `Cross-Origin-Embedder-Policy-Report-Only` first so you inventory the breakage before users find it.
go deeper
Recall that require-corp blocks cross-origin resources that have not opted in, and that the opt-in is the Cross-Origin-Resource-Policy header sent by the resource's own server.
Explain the two acceptable opt-ins — a CORP header, or a CORS-mode request with matching CORS headers — and know that a framed document has to send its own COEP header rather than a CORP one.
Show a triage order across resource classes, know credentialless drops credentials rather than relaxing the check for free, and insist on a report-only stage because the third-party long tail is not discoverable by inspection.
Frame it as a negotiation cost: decide whether the capability is worth constraining every future third-party integration, or whether the isolated workload should be moved to its own route or origin instead.
## The rule that is biting you Without COEP, embedding is permitted by default: a document may pull in any cross-origin image, font, script or frame, and the resource's server has no say. `Cross-Origin-Embedder-Policy: require-corp` inverts that. Every cross-origin subresource must now demonstrate consent, and there are exactly two acceptable demonstrations: 1. **The resource carries a CORP header.** `Cross-Origin-Resource-Policy: cross-origin` is the server saying "anyone may embed me". `same-site` narrows that to the same registrable domain. 2. **The request is made in CORS mode and succeeds.** For markup that means an explicit `crossorigin` attribute; for script it means a `fetch()` that is not `mode: 'no-cors'`. The response must carry a matching `Access-Control-Allow-Origin`. Everything else is blocked, not degraded. That is why the failure looks so abrupt: ordinary no-cors image and font loads — the overwhelming majority of third-party content on the web — satisfy neither condition. ## Triage, resource class by resource class **Images from a CDN you control.** Add the CORP header at the origin or the edge. One line, done. **Images from a third party.** Try `crossorigin="anonymous"` first: many asset CDNs already send `Access-Control-Allow-Origin: *`, in which case the CORS-mode load simply works. Note the side effect — a CORS-mode request is a *different* cache entry from the no-cors one, so expect a brief re-download. If the CDN sends no CORS headers, the image now fails hard rather than loading, so you are choosing between asking the vendor for a header and proxying the asset. **Fonts.** Usually the easiest case, because cross-origin font loading through CSS already requires CORS, so the provider is likely sending `Access-Control-Allow-Origin` already. Fonts requested from a stylesheet inherit CORS mode automatically; fonts injected via `FontFace` or preloaded need the `crossorigin` attribute on the `<link rel="preload">`. **Frames.** This is the genuinely hard class. A framed document is not covered by CORP; it must itself send a COEP header — `require-corp` or `credentialless` — or the embed is blocked. You cannot supply that from the embedder, and a third-party analytics or ad vendor has no reason to add it. Chromium supports a `credentialless` attribute on `<iframe>`, which loads the frame without credentials and therefore without requiring the frame to opt in; it is Chromium-only as of 2026 and it breaks any frame that needs the user's cookies. **Scripts and media.** Same rules as images. Classic `<script src>` loads are no-cors by default, so a third-party tag needs either CORP or `crossorigin` plus CORS on the response. ## The blunter instrument: credentialless ``` Cross-Origin-Embedder-Policy: credentialless ``` Under this value, no-cors cross-origin requests are sent *without* cookies or other credentials, and no CORP opt-in is demanded. The security argument is that an uncredentialled response cannot contain user-specific data, so pulling it into the process leaks nothing. It still qualifies the document for cross-origin isolation. It fixes most image and font breakage in one move, at a real cost: any cross-origin resource that depended on the user's cookies — a signed CDN URL backed by a session, a personalised avatar service — now returns the anonymous variant or a 401. As of 2026 it is available in Chromium and Firefox, with uneven support elsewhere, so a page relying on it must still behave sensibly where only `require-corp` exists. ## Staging the rollout Never enforce first. Deploy: ``` Cross-Origin-Embedder-Policy-Report-Only: require-corp ``` and collect reports through the Reporting API. This surfaces every resource that *would* be blocked, across real user traffic, including the long tail of assets nobody remembers embedding — a marketing pixel, a status-page widget, a legacy tag manager. Pair it with `Cross-Origin-Opener-Policy-Report-Only: same-origin` if the goal is full isolation, since COOP breakage (auth popups losing `window.opener`) is invisible in a subresource inventory. Only after the report volume goes quiet should you switch to the enforcing header. ## The strategic escape hatch If the inventory shows a vendor who will not add a header and whose frame needs credentials, the honest answer is often to stop making the page isolated. Cross-origin isolation is per-document, so a common resolution is to move the feature that actually needs it — the WebAssembly workload, the memory measurement — onto its own route or its own origin that embeds nothing, and leave the marketing-heavy pages alone. Trading one page's third-party surface for a capability is a much smaller negotiation than trading the whole product's.
- Why does adding crossorigin="anonymous" to an image sometimes cause a second download of a file the browser already had?Because CORS-mode and no-cors requests occupy different HTTP cache entries. The previously cached no-cors response cannot be reused for a CORS-mode request, so the browser refetches. On a page full of third-party images the switch can produce a visible one-off traffic spike, which is worth flagging before the change ships.
- You enable COEP: credentialless and an avatar service starts returning generic placeholder images. What happened?Credentialless strips cookies from no-cors cross-origin requests, so the avatar service no longer sees the user's session and falls back to its anonymous response. The fix is to request that resource in CORS mode with credentials and have the server send the matching CORS headers, or to proxy it through your own origin so it is no longer cross-origin.
- How would you find every resource that require-corp will block before turning it on?Deploy `Cross-Origin-Embedder-Policy-Report-Only: require-corp` with a Reporting API endpoint and let it run against real traffic for long enough to catch weekly and campaign-driven assets. Synthetic crawls and local testing systematically miss third-party tags that only fire for certain segments, geographies or logged-in states.
saying these in an interview costs you the question
- Expecting CORP on the parent page to unblock its frames
- Assuming require-corp only affects scripts and frames
- Treating credentialless as a free upgrade with no behaviour change
- Enforcing the header without a report-only stage
- Thinking a blocked resource degrades rather than failing outright