Reference guide · website-errors · Published 2026-08-16 · 3 min read

X-Frame-Options vs CSP frame-ancestors

X-Frame-Options vs CSP frame-ancestors, why frame-ancestors wins when both are set, and how to send both headers safely.

Both headers stop a page being framed by another site, which is the usual defence against clickjacking, but they are not equivalent. X-Frame-Options is the older, simpler header with only a few values. Content-Security-Policy: frame-ancestors is the newer directive that expresses the same intent more precisely and overrides the older header in modern browsers. Sending both, with the CSP directive carrying the real policy and the older header as a fallback, covers every browser.

What each does

X-Frame-Options (RFC 7034) takes one of a fixed set of values:

ValueMeaning
DENYNo other page may frame this one
SAMEORIGINOnly the same origin may frame it
ALLOW-FROM <uri>Permits one origin (not widely supported)

frame-ancestors is a CSP Level 2 directive that names which origins may frame the resource:

Content-Security-Policy: frame-ancestors 'self' https://partner.example.com

It supports 'self', 'none', and a list of origins, so it can allow several parent sites, which the older header cannot express. Note that frame-ancestors does not apply inside a meta tag; it must be sent as an HTTP header.

Precedence when both are present

Per the CSP specification, when a response carries both, frame-ancestors takes precedence and the browser ignores X-Frame-Options. This is implemented by current engines:

This is not a bug; it is the defined contract. If you deploy both and they disagree, the CSP frame-ancestors value is what modern browsers enforce, so make them agree or accept the CSP as authoritative.

Set both safely

Because the CSP value wins in modern browsers and the older header only matters for legacy clients, set them to be consistent:

X-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'self'

Troubleshooting framing failures

SymptomLikely causeFix
Page renders in Chrome but not SafariLeftover DENY plus a permissive CSPMake the CSP the policy; align the old header
Page that framed before now blockedA newly added CSP policy overrode an older lenient headerConfirm the CSP is the intended frame policy
Iframe blank but no errorThe embedded page sends frame-ancestors 'none'Relax the directive to the embedding origin
Headers missing entirelyThe server or CDN strips themAdd them at the web server or CDN layer

A page only appears to fail if the two headers conflict. The mixed content guide covers a related framing symptom, and too many redirects is a different tab error that is often mistaken for a framing problem when an iframe target redirects.

Need a website built, fixed, optimised, migrated or replaced?

This technical resource is written by CSMBAC, a small design and development studio. If you would rather hand the problem to a professional, the website service page explains how we build enquiry-ready websites.

Explore website services