Maintenance mode is the deliberate temporary unavailability of a web application during deployments, database migrations, infrastructure upgrades, or scheduled work. The application replaces its normal response (the actual site) with a placeholder "we'll be back shortly" page for the duration of the maintenance window.
The CORRECT HTTP response shape for maintenance mode:
HTTP/1.1 503 Service Unavailable
Retry-After: 3600
Content-Type: text/html; charset=utf-8
<html>
<body>
<h1>We'll be right back</h1>
<p>Scheduled maintenance until 14:00 UTC.</p>
</body>
</html>
Three things must be true:
- HTTP 503 -- "Service Unavailable" tells clients (browsers, CDNs, search engines) the response is transient.
Retry-Afterheader -- either an HTTP date or a delta-seconds value, indicating when normal service resumes.- Body text -- user-friendly message explaining the outage.
The most common mistake: returning HTTP 200 with a maintenance page body. This causes:
- Search engines update their index with the maintenance page content -- the cached/indexed version of every URL on the site becomes "We'll be right back" until re-crawled.
- CDNs cache the maintenance page -- with edge cache TTLs of hours to days, users keep seeing the maintenance page even after maintenance ends.
- Browsers don't trigger their "site might be down" UX -- chrome's "this site can't be reached" interstitial doesn't fire for HTTP 200, so users assume the site genuinely renders only the maintenance message and may abandon.
The second most common mistake: forgetting the Retry-After header. Without it, browsers can't auto-retry intelligently, and search engine crawlers may aggressively re-poll (using crawl budget on a useless page) or back off too long (delaying re-indexing of the real site).
Production-grade maintenance mode should also:
- Allow-list internal IPs so engineers can verify the deploy in production while users see the maintenance page.
- Set
Cache-Control: no-storeon the maintenance response so the maintenance page itself isn't cached anywhere downstream. - Skip the maintenance check on health-check endpoints so load balancers / monitoring don't incorrectly conclude the site is broken (and remove instances from rotation, which prolongs the outage).
- Provide a status-page link so users can self-serve incident updates.
The BeaverCheck maintenance-mode analyzer detects:
- HTTP 503 + maintenance template wording in title or body (the canonical correct shape) -- Critical finding indicating the site is currently in maintenance.
- HTTP 503 with no recognizable maintenance wording -- Warning, since 503 alone could be overload / rate-limit.
- HTTP 200 + small body + maintenance template wording -- Critical finding for the lying-status-code anti-pattern.
It deliberately requires "transient-shaped" wording ("we'll be back", "currently undergoing maintenance") rather than just the word "maintenance", which appears on FAQ / status / tutorial pages discussing maintenance schedules without being maintenance pages themselves.