[{"data":1,"prerenderedAt":173},["ShallowReactive",2],{"seo-blog/200-ok-but-broken":3},{"slug":4,"kind":5,"archetype":5,"cluster":6,"navGroup":6,"navLabel":7,"meta":8,"breadcrumbs":12,"hero":20,"sections":57,"article":169},"blog/200-ok-but-broken","hub","resources","200 OK But Broken",{"title":9,"description":10,"canonicalPath":11},"Why \"200 OK\" Doesn't Mean Your Site Works","A 200 OK only means the server answered — not that the page works. Here are the failures uptime monitoring can't see, and how to actually catch them.","/blog/200-ok-but-broken",[13,16,19],{"label":14,"href":15},"Home","/",{"label":17,"href":18},"Blog","/blog",{"label":7,"href":11},{"eyebrow":21,"headline":22,"intentStatement":23,"bullets":24,"primaryCta":34,"secondaryCta":37,"proofPanel":40},"The blind spot","200 OK Doesn't Mean It Works: The Failures Uptime Monitoring Can't See","Your monitor is green. Your checkout is dead. Both are true at the same time, and that gap is where most real incidents live. A 200 OK only proves the server answered the door — not that anything behind it works. After 15 years shipping sites for clients, the same failure kept happening: the deploy went live, the dashboard stayed green, and the client found the problem first. Here is exactly what hides behind a 200, and how to catch it.",[25,28,31],{"icon":26,"text":27},"heroicons:check-badge","Why a 200 status code is the weakest possible signal of \"working\"",{"icon":29,"text":30},"heroicons:bug-ant","The seven failures that return 200 OK while your site is broken",{"icon":32,"text":33},"heroicons:magnifying-glass","How to verify the page actually works — not just that it responded",{"label":35,"href":36},"Scan your site free","/scan",{"label":38,"href":39},"See what uptime tools miss","/website-monitoring",{"type":41,"reportTitle":42,"severity":43,"findings":44,"generatedAt":56},"report","Server says 200. Page says otherwise.","incident",[45,48,51,53],{"label":46,"status":47},"HTTP status: 200 OK","pass",{"label":49,"status":50},"main.bundle.js — 404 Not Found","fail",{"label":52,"status":50},"checkout-form.css — MIME mismatch",{"label":54,"status":55},"Result: page loads, checkout dead","info","The alert your uptime tool never sent",[58,65,79,84,111,117,135,163],{"id":59,"tocLabel":60,"type":61,"eyebrow":62,"heading":63,"html":64},"what-200-means","What 200 means","prose","The signal","A 200 OK only means the server answered","\n\u003Cp>HTTP 200 is the most reassuring number in web operations, and one of the most misleading. It means a server received a request and returned a response. That's it. It says nothing about whether the JavaScript ran, whether the stylesheet loaded, whether the checkout form submits, or whether the page a visitor sees resembles the page you shipped.\u003C/p>\n\n\u003Cp>Uptime monitoring is built almost entirely on this signal. A tool like UptimeRobot or Pingdom requests your URL every few minutes and checks for a 200. If it gets one, you're \"up.\" This is genuinely useful — you want to know the moment your server stops answering. But it's the floor of monitoring, not the ceiling.\u003C/p>\n\n\u003Cp>The trouble is that \u003Cstrong>most modern failures don't take the server down.\u003C/strong> They break something downstream — an asset, a script, a redirect, a cache layer — while the server keeps cheerfully returning 200 to every probe. Your dashboard stays green. Your visitors hit a wall.\u003C/p>\n",{"id":66,"tocLabel":67,"type":68,"stats":69},"trust","Quick stats","trust-strip",[70,73,76],{"value":71,"label":72},"200","OK — and still broken",{"value":74,"label":75},"7+","Failure types pings miss",{"value":77,"label":78},"Every asset","Sitewatch verifies per check",{"id":80,"tocLabel":81,"type":61,"eyebrow":21,"heading":82,"html":83},"failures","7 hidden failures","Seven failures that return 200 OK while your site is broken","\n\u003Ch3>1. A broken JavaScript bundle\u003C/h3>\n\u003Cp>A deploy changes a bundle hash, the old filename 404s, and the page renders as a dead shell. The HTML document still returns 200 — the missing script is a separate request your uptime monitor never makes. See \u003Ca href=\"/features/broken-assets-monitoring\">broken-assets monitoring\u003C/a>.\u003C/p>\n\n\u003Ch3>2. A stylesheet served with the wrong MIME type\u003C/h3>\n\u003Cp>A CDN cache-rule change starts serving your CSS as \u003Ccode>text/plain\u003C/code>. The browser silently rejects it and visitors see unstyled HTML. Status code: 200. Appearance: broken.\u003C/p>\n\n\u003Ch3>3. A redirect loop\u003C/h3>\n\u003Cp>A misconfigured rule sends users in circles. A ping that follows one hop and stops sees a 200 or 301 and reports success, while real browsers spin until they give up.\u003C/p>\n\n\u003Ch3>4. Content served as the wrong type\u003C/h3>\n\u003Cp>An API gateway returns JSON on a page route. The URL responds, so the ping passes — but a visitor gets a download prompt or a blank screen instead of a page. This is the heart of \u003Ca href=\"/features/website-content-monitoring\">content monitoring\u003C/a>.\u003C/p>\n\n\u003Ch3>5. A dead checkout or signup form\u003C/h3>\n\u003Cp>The page loads. The form's script 404s, or a payment provider's tag fails. The homepage returns 200, conversions go to zero, and nothing alerts. On a store this is the most expensive failure of all — see \u003Ca href=\"/woocommerce-monitoring\">WooCommerce monitoring\u003C/a>.\u003C/p>\n\n\u003Ch3>6. An expired SSL certificate behind a cache\u003C/h3>\n\u003Cp>Cached responses keep returning 200 for some visitors while others get a full-page browser security warning. Uptime tools sampling from one region can miss it entirely.\u003C/p>\n\n\u003Ch3>7. A silent content regression\u003C/h3>\n\u003Cp>A CMS edit drops your pricing section. A purge serves stale content. The page is \"up\" and returns 200 — it's just no longer the page that converts.\u003C/p>\n",{"id":85,"tocLabel":86,"type":87,"eyebrow":88,"heading":89,"steps":90},"verify","How to verify","how-it-works-stepper","The fix","How to verify a page actually works — not just that it answered",[91,96,101,106],{"number":92,"icon":93,"title":94,"description":95},"01","heroicons:arrow-down-tray","Fetch the real page","Don't just ping the URL. Fetch the document the way a browser would and read what actually came back — headers, status, and content type included.",{"number":97,"icon":98,"title":99,"description":100},"02","heroicons:code-bracket","Parse the HTML and find every asset","Extract every linked script, stylesheet, image, font, and third-party tag the page depends on. These are the requests an uptime ping never makes.",{"number":102,"icon":103,"title":104,"description":105},"03","heroicons:shield-check","Validate each one","Check the HTTP status and MIME type of every asset. A 404 script or a stylesheet served as text/plain is the difference between \"200 OK\" and \"works.\"",{"number":107,"icon":108,"title":109,"description":110},"04","heroicons:map","Confirm before you alert","Re-check from more than one region and require multiple failed checks before paging anyone. Correlated signals catch real breakage without the 3am false alarm.",{"id":112,"tocLabel":113,"type":61,"eyebrow":114,"heading":115,"html":116},"why-uptime-cant","Why pings can't","The structural limit","Why uptime tools can't do this (and that's OK)","\n\u003Cp>This isn't a knock on uptime monitors. UptimeRobot, Pingdom, Better Stack, and StatusCake do one job well: tell you the server stopped responding. The structural limit is that an HTTP ping, by design, only sees the first response — not the dozens of dependent requests that make a page actually function.\u003C/p>\n\n\u003Cp>You don't need to rip out your uptime tool. You need to fill the gap \u003Cem>above\u003C/em> it — the layer that verifies the page, not just the server. If you've outgrown ping-only monitoring, the honest comparisons live here: \u003Ca href=\"/best-uptimerobot-alternatives\">UptimeRobot alternatives\u003C/a> and \u003Ca href=\"/pingdom-alternative\">Pingdom alternatives\u003C/a>.\u003C/p>\n\n\u003Ch3>What checking the page actually looks like\u003C/h3>\n\u003Cp>Sitewatch runs uptime pings \u003Cem>and\u003C/em> full-page integrity checks: it fetches the page, parses the HTML, and validates every linked asset. When something breaks, the alert names the specific asset, its status code, and a plain-English root cause — not just \"your site is down.\" That's the difference between an alert you investigate for an hour and one you fix in minutes.\u003C/p>\n",{"id":118,"tocLabel":119,"type":120,"heading":121,"items":122},"faq","FAQ","faq-accordion","\"Up but broken\" FAQ",[123,126,129,132],{"question":124,"answer":125},"If the server returns 200, how can the site be broken?","A 200 means the HTML document was returned successfully. But a modern page depends on dozens of additional requests — scripts, stylesheets, images, fonts, API calls. Any of those can fail (404, wrong MIME type, timeout) while the original document still returns 200. The page is technically \"up\" and functionally broken.",{"question":127,"answer":128},"Doesn't my uptime monitor already catch this?","No — and that's expected. Uptime monitors check whether the server responds to a single request. They don't fetch and validate the assets the page depends on, so a broken bundle, a stale CDN file, or a dead checkout script all return 200 and pass the check.",{"question":130,"answer":131},"What's the difference between a false positive and \"up but broken\"?","A false positive is an alert that fires when nothing is wrong. \"Up but broken\" is the opposite — a real problem that never fires an alert at all (a false negative). False negatives are worse: you find out from a customer.",{"question":133,"answer":134},"How do I start catching these failures?","Run a free scan of any URL — Sitewatch fetches the page, validates every asset, and shows you what's broken behind the 200, with no signup required. From there you can turn the scan into continuous monitoring.",{"id":136,"tocLabel":137,"type":138,"eyebrow":139,"heading":140,"links":141},"related","Related","related-links-grid","Keep reading","Related resources",[142,145,150,154,159],{"label":143,"href":39,"description":144,"icon":103},"Website Monitoring","The layer above uptime — every page, asset, and SSL cert.",{"label":146,"href":147,"description":148,"icon":149},"Best UptimeRobot Alternatives","/best-uptimerobot-alternatives","7 tools compared if you've outgrown ping-only checks.","heroicons:scale",{"label":151,"href":152,"description":153,"icon":149},"Pingdom Alternative","/pingdom-alternative","Catch broken deploys and asset failures Pingdom misses.",{"label":155,"href":156,"description":157,"icon":158},"Content Monitoring","/features/website-content-monitoring","Catch a dropped price, a removed CTA, or stale content.","heroicons:document-text",{"label":160,"href":161,"description":162,"icon":149},"Uptime vs Website Monitoring","/blog/uptime-vs-website-monitoring","Why the distinction decides what you catch.",{"id":164,"tocLabel":165,"type":166,"heading":167,"subtext":168,"primaryLabel":35,"primaryHref":36},"cta","Try Sitewatch","cta-strip","See what your 200 OK is hiding","Paste a URL. Sitewatch fetches the page, validates every asset, and shows you what's broken behind the green status. Free, no signup to see results.",{"headline":22,"datePublished":170,"authorName":171,"authorUrl":172},"2026-06-26","Nicky Christensen","https://www.linkedin.com/in/dknickychristensen/",1782469219872]