A Broken-Link Check Counts 404s. The Resource That Breaks Your Padlock Returns 200.
A broken-link checker does one well-defined thing: it walks the <a href> links on a page, fetches each target, and flags the ones that come back wrong — a 4xx, a 5xx, a timeout, a connection that never opens. That answers a real question: which links point at something that isn't there. Run a clean scan and you get a green report and a reasonable feeling that the page is healthy.
But "every link resolves" and "this page works in a browser" are not the same claim, and the gap between them is a resource class a status-code check is structurally blind to. The resource most likely to visibly break an HTTPS page doesn't fail with a status at all. It returns 200. It's mixed content — an http:// subresource loaded by an https:// page — and because the resource genuinely exists, a checker that grades links on their HTTP status waves it straight through.
The 200 that still breaks the page
When a page served over https:// pulls in a subresource over plaintext http:// — an image, a script, a stylesheet, an iframe — that's mixed content. The subresource itself is usually fine: request it directly and it's a healthy 200. Nothing is "broken" in the sense a link checker means. The break happens in the browser, on the security boundary, and it depends on what kind of resource it is:
- Active mixed content — a
<script>, a stylesheet<link>, or an<iframe>overhttp://— is blocked outright. The browser refuses to load it on a secure page. A blocked script means the JavaScript that depended on it silently doesn't run; a blocked stylesheet means the page renders unstyled. No 404 anywhere — the file was reachable, the browser just won't use it. - Passive mixed content — an
<img>,<video>, or<audio>overhttp://— modern browsers try to auto-upgrade tohttps://, and if that secure version doesn't exist, they block it too. Either way the padlock stops being a clean padlock: the address bar drops to "Not fully secure," and on the blocked case you get a missing image on a page whose image URL returns a perfectly good200overhttp.
So the failure is real and user-visible — a dead script, an unstyled page, a broken image, a downgraded padlock — but it is invisible to any tool that decides "broken" by fetching a URL and reading its status code. The URL isn't broken. The combination of a secure page and an insecure subresource is.
Why it shows up silently
Mixed content is rarely typed in on purpose. It leaks in on a timeline you don't control:
- A third-party embed — an analytics snippet, a chat widget, an ad tag, an old badge — hardcodes an
http://script URL. - A CDN or asset host is referenced with an absolute
http://URL that survives a move to HTTPS because nothing ever re-fetched it to notice. - A protocol migration flips the site to HTTPS but leaves absolute
http://URLs baked into content, a theme, or a database field. - A
Content-Security-Policythat hadupgrade-insecure-requestsgets relaxed to ship one stubborn widget, and every previously-upgraded subresource quietly reverts.
Every one of those ships green through a broken-link check, because every one of those URLs answers 200.
How to actually find it
Mixed content is found by looking at the protocol of the subresources a secure page loads, not the status of its links:
- The browser console is the ground truth: it logs
Mixed Content:warnings for every upgraded or blocked resource, and the padlock's site-information panel tells you the page isn't fully secure. This catches resources injected by client-side JavaScript, which a static scan of the served HTML can't see. - CSP turns it into a signal you don't have to eyeball:
Content-Security-Policy-Report-Only: block-all-mixed-content(or the reporting directives) will report every insecure subresource without breaking anything, so you can find them before you enforce. - A checker that inspects subresource protocols — not just link statuses — catches the ones present in the served HTML in a single pass.
The free broken-links checker does both halves in one scan: it walks the page's <a href> links and reports the ones that return an error status or time out or fail to connect — and, separately, it reads the page's <img>, <script>, stylesheet, and <iframe> subresources and flags every one loaded over http:// on an https:// page as mixed content, with the exact insecure URLs. It reads the HTML the server sends, so resources injected later by client-side JavaScript still need the browser console — but the hardcoded http:// embeds that cause most real mixed-content breakage are exactly the ones in that served HTML. No signup, one page at a time.
What a link check is good for — and what to check past it
A broken-link check isn't the wrong tool; it's a narrow one. Dead outbound links, a deleted product page still linked from your nav, a 5xx on a resource you own — all real, all worth catching, all what a status check is for. Just don't read "every link resolves" as "this page is fine over HTTPS." Once the links are clean, the questions a status code can't answer are:
- Does any
http://subresource load on anhttps://page? (Mixed content — the padlock and the blocked-script break.) - Does the page's sitemap point at URLs that are actually reachable? (A sitemap listing dead
<loc>entries misroutes crawlers, and it's another thing a spot-check of visible links skips.)
The one-line version: a broken-link check grades URLs by their status code, and mixed content is the failure that keeps a perfect status code while breaking the page — a 200 resource the browser blocks, on a secure page whose padlock quietly downgrades. Check the links, then check whether any of them are insecure subresources on a secure page.
And it comes back. A redeploy that re-adds an old widget, a CDN swap, a CSP relaxed to ship one integration — each reintroduces an http:// subresource that answers 200 and passes the next link check exactly like it passed the last one. Merlonix crawls your site on a schedule, finds broken links and mixed content across every page, and alerts you the moment a new one appears — the same way it watches SSL and DNS: continuously, from outside your stack, so a padlock that silently went from clean to "not fully secure" is something you hear from monitoring, not from a customer. Run the free broken-links scan to see where a page stands right now, and browse the rest of the free tools while you're there.