Skip to main content

Catch Blank HTTP 200 Pages with Content and Browser Checks

GuideWritten by oncall.fyi editorialPublication approved by Burak YApproval recorded 12 September 2026
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.

javascript
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 fixtureExpected outcome
HTTP 200 containing only a titleContent or browser assertion fails
Main JavaScript asset returns 404Browser assertion fails with asset evidence
Empty API payload with HTTP 200Known fixture assertion fails
Slow but valid rendering within the agreed deadlineTest passes
Runner disabledIndependent 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.

  1. Writing Playwright tests Microsoft. Checked 12 September 2026.
  2. 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