X-Frame-Options conflicts with frame-ancestors or is invalid alongside it

In the reportX-Frame-Options and frame-ancestors disagree

frame_policy_conflict · Review item

Short answer

This security advice appears when a page sends X-Frame-Options and a Content-Security-Policy header with frame-ancestors, and they describe different framing rules, or X-Frame-Options has a value other than DENY or SAMEORIGIN. Two headers that disagree are easy to misread when you maintain them, and browsers ignore some values. Make the two agree, or keep one.

Severity: Notice. Security advice in Good to know. Align the captured framing headers for maintainability; this narrow comparison does not test browser behaviour or ranking.

Why it matters

MDN points to the frame-ancestors directive of a Content Security Policy for more comprehensive control than X-Frame-Options offers, and notes that modern browsers ignore an X-Frame-Options header that uses the obsolete ALLOW-FROM directive.

What to do

  1. Look at the finding: it shows the X-Frame-Options values, the CSP headers and the framing rule we resolved from frame-ancestors.
  2. Decide who may frame the page and state it in frame-ancestors.
  3. Set X-Frame-Options to the matching value, DENY for 'none' or SAMEORIGIN for 'self', or remove it.

When to leave it as it is: if you keep the older header on purpose for browsers that do not support frame-ancestors, and accept that they follow its rule, you can leave it.

What we read

We read the final response headers of each crawled page with our own user agent. A page is judged when it has an X-Frame-Options header and at least one Content-Security-Policy header with frame-ancestors; a frame-ancestors in a <meta> tag does not count.

Across the page's header policies, we resolve frame-ancestors to deny when one policy has no allowed source, to same-origin when every resolved source list is only 'self', and to allow-all for the simple * case. The page is reported when X-Frame-Options has a value other than DENY or SAMEORIGIN, more than one distinct value, or a value that differs from a resolved rule; frame-ancestors * conflicts with a valid restrictive X-Frame-Options value.

Host or scheme source lists are not resolved against a valid X-Frame-Options value, so that comparison is not checked. An invalid X-Frame-Options value is still reported even when the frame-ancestors outcome is unresolved. Pages with the same captured header texts are reported together, one finding per exact combination.

Example & evidence

Illustrative example — one response, not a live audit.

https://bakery.example/ sends:

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

frame-ancestors 'self' lets the site's own pages frame it, while DENY lets no page, so the page is reported.

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

A possible correction: make the older header match.

Confirm & check again

Check for yourself: open the page's response headers and compare X-Frame-Options with frame-ancestors in Content-Security-Policy: DENY matches 'none', and SAMEORIGIN matches 'self'.

Check again: Full audit — run a new full audit. With complete captured headers, this header-combination finding closes only when no currently crawled page still emits the same conflict; a new page with the old combination keeps it open. Changing either header creates a new combination to evaluate, and removing X-Frame-Options makes this rule inapplicable there. An unresolved host or scheme comparison cannot prove a prior conflict fixed.

Limits & sources

An invalid X-Frame-Options is reported only when a frame-ancestors header is also present. Host and scheme source lists are not resolved against a valid X-Frame-Options value, and framing is not tried in a browser. A changed header combination is reported separately if it still meets this rule.

Confidence: High because both headers are read directly.

Sources

  • MDN, X-Frame-Options header — points to the frame-ancestors directive for more comprehensive control, and notes that modern browsers ignore a header with the obsolete ALLOW-FROM directive. Checked 28 September 2026.

Editorial review: 2 November 2026