What happens
On a Cloudflare-proxied site with Email Address Obfuscation enabled, every mailto: anchor in the served HTML is rewritten to /cdn-cgi/l/email-protection#<hex>. The crawler follows that href (same origin, http), gets a 404 — Cloudflare's edge never serves that path; the fragment is decoded client-side by email-decode.min.js — and reports two things:
- one
broken-internal-link (critical) per source page carrying the link, deduped per target: 181 rows in our audit, all with the same target;
- one
broken-page for the helper URL itself, because that URL also enters the frontier and is crawled.
Measured on a live Cloudflare-proxied site (site audit 5d9a4197, 182 pages): 181 broken-internal-link plus 1 broken-page, one distinct target, always /cdn-cgi/l/email-protection. Both the bare path and the full href including the fragment return 404 over plain HTTP.
Why the site cannot fix it
The path is not site content and cannot be routed by the site: Cloudflare reserves /cdn-cgi/. There is nothing to redirect and nothing to repair. Our verification on that site: 0 occurrences of cdn-cgi in the source, the fragment decodes to the real address, and a real browser resolves all 10 distinct contact-link implementations to working mailto: links.
Root cause in this repo
src/server/features/audit/scratchpad-sql.ts → BROKEN_LINKS_SQL flags every internal link whose crawled target has status_code >= 400 AND fetch_class = 'ok'. AuditScratchpad.ts already states the principle: "Blocked targets (WAF challenges) are excluded: a 403 from bot protection is not evidence of a broken link." A Cloudflare helper 404 is the same class of response — a protection artefact, not a broken link — but because it is a plain 404 it is not covered by that exclusion. src/server/lib/audit/url-policy.ts blocks only SSRF/private hosts, so /cdn-cgi/… is crawled.
Suggested fix (either)
- Narrow: in
BROKEN_LINKS_SQL, skip targets whose path matches /cdn-cgi/l/email-protection.
- General: treat
/cdn-cgi/ as non-content space for crawling and link targets. Cloudflare reserves that prefix for its own helpers, so nothing under it is site content. This also removes the bogus page-level 404 and saves crawl budget.
Evidence that this clears it without hiding real 404s
With Email Address Obfuscation turned off on the same site — so the HTML carries real mailto: links — the identical crawl (182/182 pages, audit 32ece3c8) reports 0 broken-internal-link and 0 broken-page. Genuinely broken links would still be reported. The exclusion is specific to a path that cannot be content; it is not a suppression mechanism for arbitrary 404s.
Provenance
Measurements come from a production site audit run with this tool (two crawls, 182 pages each, before and after the obfuscation setting changed). Underlying data available on request.
Happy to open a PR with either fix if that is easier for you than doing it from this report.
What happens
On a Cloudflare-proxied site with Email Address Obfuscation enabled, every
mailto:anchor in the served HTML is rewritten to/cdn-cgi/l/email-protection#<hex>. The crawler follows that href (same origin, http), gets a 404 — Cloudflare's edge never serves that path; the fragment is decoded client-side byemail-decode.min.js— and reports two things:broken-internal-link(critical) per source page carrying the link, deduped per target: 181 rows in our audit, all with the same target;broken-pagefor the helper URL itself, because that URL also enters the frontier and is crawled.Measured on a live Cloudflare-proxied site (site audit
5d9a4197, 182 pages): 181broken-internal-linkplus 1broken-page, one distinct target, always/cdn-cgi/l/email-protection. Both the bare path and the full href including the fragment return 404 over plain HTTP.Why the site cannot fix it
The path is not site content and cannot be routed by the site: Cloudflare reserves
/cdn-cgi/. There is nothing to redirect and nothing to repair. Our verification on that site: 0 occurrences ofcdn-cgiin the source, the fragment decodes to the real address, and a real browser resolves all 10 distinct contact-link implementations to workingmailto:links.Root cause in this repo
src/server/features/audit/scratchpad-sql.ts→BROKEN_LINKS_SQLflags every internal link whose crawled target hasstatus_code >= 400 AND fetch_class = 'ok'.AuditScratchpad.tsalready states the principle: "Blocked targets (WAF challenges) are excluded: a 403 from bot protection is not evidence of a broken link." A Cloudflare helper 404 is the same class of response — a protection artefact, not a broken link — but because it is a plain 404 it is not covered by that exclusion.src/server/lib/audit/url-policy.tsblocks only SSRF/private hosts, so/cdn-cgi/…is crawled.Suggested fix (either)
BROKEN_LINKS_SQL, skip targets whose path matches/cdn-cgi/l/email-protection./cdn-cgi/as non-content space for crawling and link targets. Cloudflare reserves that prefix for its own helpers, so nothing under it is site content. This also removes the bogus page-level 404 and saves crawl budget.Evidence that this clears it without hiding real 404s
With Email Address Obfuscation turned off on the same site — so the HTML carries real
mailto:links — the identical crawl (182/182 pages, audit32ece3c8) reports 0broken-internal-linkand 0broken-page. Genuinely broken links would still be reported. The exclusion is specific to a path that cannot be content; it is not a suppression mechanism for arbitrary 404s.Provenance
Measurements come from a production site audit run with this tool (two crawls, 182 pages each, before and after the obfuscation setting changed). Underlying data available on request.
Happy to open a PR with either fix if that is easier for you than doing it from this report.