Catch Blank HTTP 200 Pages with Content and Browser Checks
Sources and verification
- Source dates
- Oldest source check: 12 September 2026.
- Technical verification
- Separate technical verification has not been recorded.
Publication approval and technical verification are recorded separately. Automated link checks establish reachability, not accuracy. A checked example verifies only its stated test cases, not the whole article or your production setup.
In short
A successful HTTP response can contain an empty application shell. Check a stable marker in the returned content, then use a browser test when JavaScript must render the useful interface. Send a success heartbeat only after assertions pass. Test a deliberately blank page and a broken script so a reachable server cannot conceal a failed user experience.
Key takeaways
- HTTP status alone cannot prove the interface rendered.
- A browser assertion should identify useful content, not just a page title.
- The browser runner needs an independent missed-run alarm.
Identify the smallest useful success condition
A reverse proxy can deliver a valid HTML document while a misplaced rewrite, missing asset, or JavaScript exception leaves users staring at a blank screen. A title tag usually survives these failures. Start with the action the visitor needs: see a library, open a dashboard, or retrieve one known record.
Inspect the actual response body. If the useful content is rendered on the server, require a stable heading or structured JSON value as well as the expected status. Choose a marker that cannot appear inside an error template. If the initial document contains only an application root and scripts, a keyword check against that document cannot establish that the application rendered.
Assert the rendered result
Use a separate synthetic test account with access only to non-sensitive fixture data. This Playwright test (opens in a new tab) waits for a meaningful interface element; the host and accessible names are placeholders you must replace with your application's real contract.
import { test, expect } from '@playwright/test';
test('the library renders a known fixture', async ({ page }) => {
const response = await page.goto('https://library.example.com/');
expect(response?.status()).toBe(200);
await expect(page.getByRole('heading', { name: 'Library', exact: true }))
.toBeVisible();
await expect(page.getByText('Monitoring fixture book', { exact: true }))
.toBeVisible();
});
Pin the test dependency and browser version in the runner. Set an overall execution deadline and capture a screenshot, browser console errors, and failed asset URLs when assertions fail. Do not put session tokens or private page contents into a public alert. A short error summary can link to restricted artifacts.
Run the test through the deployment's public hostname so the proxy, TLS, assets, and frontend configuration are included. An origin-only check is useful separately, but it may bypass the exact Caddy or Nginx rule that caused the blank page.
Connect the result to monitoring
The runner should send success only when the test command exits successfully. A command chain joined with && can enforce this; a cleanup hook that always sends success cannot. Keep the heartbeat URL in a restricted secret store and never include it in screenshots or logs.
A receiver with a missed-run deadline (opens in a new tab) catches a stopped runner. Distinguish assertion failure from missing execution and failed heartbeat delivery. The last two indicate a monitoring problem; neither proves the application itself failed.
Prove the blind spot is closed
| Controlled fixture | Expected outcome |
|---|---|
| HTTP 200 containing only a title | Content or browser assertion fails |
| Main JavaScript asset returns 404 | Browser assertion fails with asset evidence |
| Empty API payload with HTTP 200 | Known fixture assertion fails |
| Slow but valid rendering within the agreed deadline | Test passes |
| Runner disabled | Independent deadline alert fires |
Make these changes in a test deployment. A passing screenshot from the healthy version is only a baseline; the broken fixtures establish detection. Review the fixture after UI changes so the test continues to represent a real user outcome. Add deeper transactions separately when rendering alone does not cover the service promise.
Did this help?
Your answer helps us improve this guide. We save only the page and your choice for 30 days.
No name, email, or incident details are requested.
Sources
Vendor facts change. Each source below shows the date this page last checked it.
- Writing Playwright tests — Microsoft. Checked 12 September 2026.
- Configuring deadline and heartbeat checks — Healthchecks. Checked 12 September 2026.
Related
One practical idea, occasionally
The On-Call Brief: short field notes, templates, and operational lessons.
Follow the field guide
Email subscriptions are not open yet. Read new guides in your feed reader — no email address needed.
Subscribe with RSS