Response header
< Cross-Origin-Embedder-Policy: require-corpCross-Origin-Embedder-Policy
Learn how Cross-Origin-Embedder-Policy (COEP) controls cross-origin resource loading. Required for SharedArrayBuffer and high-resolution timer access.
- Direction
- Response
- Category
- Security
- Spec
- HTML Standard
On this page
TL;DR: Send
Cross-Origin-Embedder-Policy: require-corptogether withCross-Origin-Opener-Policy: same-originon your HTML to make the page cross-origin isolated, which unlocksSharedArrayBufferand precise timers. The catch: every cross-originno-corsasset then needs aCross-Origin-Resource-Policyheader, and CORS-mode assets must pass CORS.credentiallessis the easier option, because it loadsno-corsassets without credentials instead of demanding CORP.
What is Cross-Origin-Embedder-Policy?
COEP is a policy on a document’s response that controls which cross-origin content that document may load. It can’t grant permission on a CDN’s behalf, and it doesn’t turn an ordinary no-cors image request into a CORS request. Whether an asset loads comes down to the asset’s request mode and its own response headers. MDN lays out the rules for each mode.
Syntax
Cross-Origin-Embedder-Policy: require-corp
Put it on the HTML response. Adding it only to API responses or asset files has no effect on the page.
Value Guide
unsafe-noneis the default and adds no COEP restriction. Ordinary CORS and CORP rules still apply.require-corplets a cross-originno-corsasset load only if it sends a suitable CORP header; CORS-mode loads must succeed under CORS.credentiallesslets cross-originno-corsloads through without CORP by sending them without credentials and ignoring any cookies in the response. CORS-mode requests still need CORS permission, and an asset that sends a restrictive CORP is still blocked.
Example
The headers on the document response (headers on this page are trimmed examples):
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Then check the result in the served page:
console.log(window.isSecureContext, window.crossOriginIsolated)
Isolation also requires a secure context and a cross-origin-isolated permissions policy that allows it. MDN documents the capability check. Trust crossOriginIsolated, not the header.
Implementation
In nginx, add these to the server or location that serves the document:
add_header Cross-Origin-Opener-Policy "same-origin" always;
add_header Cross-Origin-Embedder-Policy "require-corp" always;
The always parameter adds the headers to error responses too. Watch for nested locations with their own add_header directives, because those replace the inherited ones.
In an existing Express app, register middleware for the document before the route that serves the HTML:
app.use('/isolated', (_req, res, next) => {
res.set({
'Cross-Origin-Opener-Policy': 'same-origin',
'Cross-Origin-Embedder-Policy': 'require-corp'
})
next()
})
app.get('/isolated', (_req, res) => {
res.sendFile('isolated.html', { root: '/srv/app/public' })
})
The route expects /srv/app/public/isolated.html to exist. Express covers header middleware and rooted file responses. Scope these headers to pages that need isolation, then test their resources and popup flows.
Why Pages Break After Enabling COEP
A plain cross-origin image loads in no-cors mode. Under require-corp, you have two fixes: the provider returns Cross-Origin-Resource-Policy: cross-origin, or you request the image in CORS mode:
<img src="https://cdn.example.com/logo.png" crossorigin="anonymous" alt="Logo">
The CORS route needs the CDN to answer this anonymous request with a matching Access-Control-Allow-Origin or *. That header alone won’t help while your page still makes a no-cors request. Fonts are always loaded with CORS, so a font that fails its CORS check stays broken no matter what CORP header you add.
Rollout Strategy
Start in report-only mode to find violations without enforcing anything. Assuming you run the report endpoint:
Reporting-Endpoints: coep="https://reports.example.com/coep"
Cross-Origin-Embedder-Policy-Report-Only: require-corp; report-to="coep"
The report-only header only reports; it doesn’t isolate the page. Report delivery varies by browser, so also test the real page with DevTools open.
Enabling COEP Without Breaking Your Page
Audit request modes before you touch asset headers. A third-party script might load as no-cors, while a module script or font needs CORS. Cross-origin iframes add their own document-policy requirements, so putting CORP on the child document is only part of the fix.
COEP credentialless isn’t a general fix for third-party iframes. The separate, experimental <iframe credentialless> attribute loads the frame in an ephemeral context and relaxes the embedding rules for it. Test it in every browser you support before you rely on it.
Related Headers
Frequently asked questions
What is Cross-Origin-Embedder-Policy?
COEP controls cross-origin loading by request mode. With require-corp, cross-origin no-cors assets need CORP permission, while CORS-mode assets must pass CORS.
What values can COEP have?
The values are unsafe-none, require-corp, and credentialless. The default is unsafe-none; credentialless drops credentials only for cross-origin no-cors resource loads.
Why does COEP break my images?
A no-cors cross-origin image needs an appropriate CORP header under require-corp. Alternatively, add crossorigin and have the image server permit that CORS request.
How do COOP and COEP work together?
COOP same-origin with COEP require-corp or credentialless can enable cross-origin isolation in a secure context, provided permissions policy does not block the capability. Check window.crossOriginIsolated.
Sources
Related
Reporting-Endpoints Header: Reporting API Setup
Reporting-Endpoints names the URLs where browsers send CSP, COOP, deprecation and crash reports. Syntax, the default endpoint, and replacing Report-To.
Access-Control-Allow-Credentials Header
Learn how Access-Control-Allow-Credentials controls whether browsers expose responses when credentials (cookies, auth headers) are included in CORS requests.
Access-Control-Allow-Headers Header
Learn how Access-Control-Allow-Headers specifies which custom HTTP headers can be used during cross-origin requests in CORS preflight responses.
Access-Control-Allow-Methods Header
Learn how Access-Control-Allow-Methods specifies which HTTP methods are permitted for cross-origin requests in CORS preflight responses.