ScreenshotNeo

BlogEngineering

How to Diagnose Cloudflare Outages That Break Website Screenshots

Classify Cloudflare screenshot failures, collect reproducible evidence, distinguish edge and origin errors, and verify recovery with curl and DevTools.

By the ScreenshotNeo team30 September 20269 min read

How to Diagnose Cloudflare Outages That Break Website Screenshots

A screenshot can fail even when a site appears to work in your browser because the failure may be at Cloudflare’s edge, DNS, Workers, the origin connection, or the application itself. The image alone cannot identify the layer. Diagnose the request and its response headers, then compare the same URL across the affected region, a healthy region, and (when you control the zone) the direct origin.

The shortest reliable workflow is:

  1. Record the exact URL, UTC time, runner region, browser version, HTTP status, and whether the result is blank, a Cloudflare error page, or a page with missing assets.
  2. Check Cloudflare’s official status API and regional status view before changing DNS or proxy settings.
  3. Save response headers and body with curl; inspect the document and every dependent asset in DevTools.
  4. Classify the response using cf-error-type, cf-error-origin, cf-ray, edge status, origin status, and cache state.
  5. If authorized, compare Cloudflare-proxied traffic with a direct-origin or DNS-only request.
  6. After a fix, rerun the exact screenshot from the same region and verify the full asset chain.

What a screenshot failure can mean

A screenshot service is a browser client. It receives whatever the browser would receive from the selected network location and profile. A white or incomplete image therefore does not prove that Cloudflare is down. Common layers are:

Classify the failing layer by comparing edge, DNS, Worker, origin, and browser evidence.
Classify the failing layer by comparing edge, DNS, Worker, origin, and browser evidence.
Layer Typical signal What to investigate
Cloudflare incident Several unrelated domains or regions fail at the same time; status page reports degradation or outage. Cloudflare Status API, component and region view, timestamps.
DNS or routing Resolution errors, cf-error-type: 1000 or 1016. Records, CNAME targets, DNSSEC, origin hostname resolution.
Workers 1101 or 1102, often with a generated error page. Worker exception, resource limit, route, and recent deployment.
Origin connectivity 521–526, connection refusal, TLS failure, or timeout. Listening port, firewall allowlist, certificate, and network path.
Origin response Branded 502/504 or an application error body. Origin load, crashes, upstream dependencies, and request logs.
Browser rendering Document is 200 but CSS, JavaScript, fonts, images, or API calls fail. DevTools Network panel and a sanitized HAR.

Cloudflare’s status model labels components as operational, degraded performance, partial outage, or major outage. Check the official status API and the regional status page before changing production configuration.

1. Establish scope and timing

Create an incident record before refreshing repeatedly. Include:

  • Full URL, including path and query string.
  • UTC timestamp and the local timezone used by the operator.
  • Screenshot runner region, browser version, viewport, and user agent.
  • HTTP status and response headers.
  • cf-ray value, if present.
  • Whether the image is blank, an error page, partially rendered, or missing assets.
  • One successful reference URL or region, if available.

Run the same URL from at least two locations when possible. A failure in one region with success elsewhere suggests regional edge, routing, DNS propagation, or origin allowlisting behavior. A failure for every region points toward a global incident, DNS, Worker, or origin problem.

2. Read the HTTP response, not only the image

Save both headers and body. The body often contains the Cloudflare error page or an application message that a screenshot crop hides.

curl -sS -D headers.txt -o body.html https://example.com/path
printf 'HTTP status: '
curl -sS -o /dev/null -w '%{http_code}\n' https://example.com/path

Review headers.txt for cf-ray, cache headers, cf-error-type, cf-error-origin, content type, and server timing. Cloudflare-generated pages can identify classes such as:

  • 1000: DNS resolution failure.
  • 1016: origin DNS error.
  • 1101 and 1102: Workers runtime failure or resource limit.
  • 52x: origin connectivity or TLS classes.

A branded 502 or 504 generally means Cloudflare is reporting an origin response. An unbranded blank 502/504 can indicate a Cloudflare-side response. Cloudflare lists excessive origin load, crashes, network failures, and timeouts among common origin causes; compare the response body and headers with your origin logs.

Inspect the browser request sequence

Open an Incognito or Private window, load the URL, and open DevTools → Network. Preserve the log, reload, and inspect:

  • The document request and redirect chain.
  • CSS, JavaScript, fonts, images, and API calls.
  • Blocked, canceled, or timed-out requests.
  • Status, response headers, and initiator for each failed asset.

Export a HAR for visual issues, broken elements, slow loads, or when you need the complete request sequence. Sanitize cookies, authorization headers, payment data, private keys, and other credentials before sharing it. Cloudflare specifically recommends HAR files for this class of evidence.

3. Separate Cloudflare, DNS, and origin failures

Only perform direct-origin tests when you control the zone and origin and understand the security impact. Preserve the original proxy configuration and roll back temporary DNS changes immediately after the comparison.

Direct origin with a Host header

If your origin has a stable hostname or IP, send the original host name in the request. This tests the origin virtual host while bypassing the Cloudflare edge:

curl -sS -D origin-headers.txt \
  -H 'Host: example.com' \
  -o origin-body.html \
  https://ORIGIN_HOSTNAME/path

Use the correct scheme and certificate for your origin. A certificate mismatch, firewall rejection, or missing virtual-host configuration can make a direct test fail even when Cloudflare is healthy, so record the exact command and error.

Controlled DNS-only comparison

For a temporary, authorized comparison, switch the record to DNS-only or use a separate test hostname that points at the origin. Do not leave a production origin exposed longer than necessary. Compare:

Comparison Question answered
Proxied versus direct origin Does the origin generate the same status and body without Cloudflare?
Affected versus healthy region Is the problem regional or global?
Document versus assets Does the page load while dependencies fail?
Edge versus origin status Did Cloudflare generate the response or pass one through?

4. Handle Cloudflare 520 correctly

Error 520 needs extra evidence. Collect the full URL, cf-ray, output from /cdn-cgi/trace, and two HAR files: one with Cloudflare enabled and one with it temporarily disabled or bypassed under your controlled procedure.

curl -sS https://example.com/cdn-cgi/trace -o trace.txt
cat trace.txt

In Log Explorer or Logpush, compare edgeResponseStatus, originResponseStatus, and CacheStatus. Never interpret OriginResponseStatus=0 by itself:

  • CacheStatus=hit or revalidated with origin status 0 can be expected because no origin request was needed.
  • CacheStatus=miss or expired with origin status 0 indicates that Cloudflare contacted the origin but received no usable HTTP response.

Correlate the Ray ID and timestamp with origin access logs. This prevents blaming the origin for a cache-served response or blaming Cloudflare for an application crash.

5. Classify common status codes

Code or type Likely class Next action
1000 / 1016 DNS record or origin target problem. Check records, CNAME targets, and whether any record points at a Cloudflare IP or an unresolvable target.
1101 / 1102 Workers exception or resource limit. Inspect Worker telemetry and test the route without the failing Worker when safe.
521 Origin refused or could not accept the connection. Verify the service is listening and Cloudflare ranges are allowed through the firewall.
522 Connection or response timeout to origin. Check origin load, network ACLs, and slow upstream operations.
523 Origin unreachable. Check routing, IP announcements, firewall policy, and host availability.
524 Connection established but origin did not respond in time. Profile long requests and move slow work out of the synchronous page request.
525 / 526 TLS handshake or certificate validation issue. Verify certificate chain, hostname, expiry, and Cloudflare SSL mode.
502 / 504 Origin-generated or Cloudflare-generated gateway response. Use branding, headers, body, and origin logs to identify which side produced it.

6. Verify recovery

Recovery means the screenshot job succeeds from the previously affected region and the page is complete. Rerun the exact URL with the same browser profile, viewport, and timing. Confirm:

A clean capture separates page content from overlays that can obscure diagnostic evidence.
A clean capture separates page content from overlays that can obscure diagnostic evidence.
  • The main document returns the expected status and content type.
  • Stylesheets and scripts load without console errors.
  • Fonts, images, and lazy-loaded content appear.
  • API calls return expected responses.
  • Headers no longer show the failing error class.
  • A before-and-after HAR or header capture matches the incident timeline.

Keep the incident ID, UTC timestamps, Ray IDs, commands, and sanitized artifacts. These records make recurring regional or origin failures measurable and give your hosting provider the specific code, time, and URL Cloudflare requests for 5XX investigations.

Or skip the browser setup

If you need a clean capture while diagnosing an endpoint, ScreenshotNeo provides a single GET request that returns PNG, JPEG, WebP, or PDF. See the ScreenshotNeo API documentation for the complete parameter list.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo accepts cookie and consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response reports the page verdict and billing state in X-Page-Verdict and X-Billed headers. Its MCP server includes take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.

You can also set full-page capture, lazy-image loading, CSS element capture, dark mode, device presets, custom viewport and retina scale, PDF paper and margins, custom CSS or JavaScript, clicks, waits, request blocking, headers, cookies, user agent, authorization, timezone, geolocation, transparent backgrounds, resizing, cache TTL, signed links, asynchronous webhooks, bulk capture for up to 100 URLs, and usage reporting. The parameter names used by other screenshot APIs also work, which simplifies migrations.

The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 screenshots; every feature is available on every plan. Create a free ScreenshotNeo account.

Performance, reliability, and cost notes

  • Reduce false diagnoses: Keep URL, region, browser, and wait settings identical between attempts. Changing all four at once hides the causal layer.
  • Capture evidence efficiently: Save headers first, then a body and HAR. Repeated full screenshots add little diagnostic value when the document request is already failing.
  • Account for cache: A cache hit can legitimately show origin status 0. Record cache state before escalating.
  • Protect the origin: Direct-origin tests and cache bypasses can increase load. Run them briefly and from one controlled client.
  • Control screenshot spend: ScreenshotNeo bills only clean shots; bot checks, blank pages, timeouts, failed loads, and cache hits are free. Its cache TTL and asynchronous jobs can reduce duplicate work during incident analysis.
  • Use regional checks: A single successful browser run does not prove global recovery. Repeat from the region that failed and at least one independent region.

Troubleshooting checklist

The browser works, but the screenshot is blank

Check the screenshot runner’s status code, headers, and region. Compare the document and asset requests in DevTools. A bot challenge, geolocation rule, missing font, JavaScript exception, or blocked API can produce a blank image even when an interactive browser session succeeds.

The page shows 520 but the origin looks healthy

Collect Ray ID, trace output, paired HAR files, cache state, and edge/origin status fields. A cache hit with origin status 0 is not proof of an origin failure; a miss or expired cache with 0 needs origin connectivity investigation.

Only one geography fails

Run the same URL from a second region and compare DNS answers, Ray IDs, firewall decisions, and asset requests. Check regional Cloudflare status and origin allowlists before changing global DNS.

Direct origin succeeds but proxied traffic fails

Inspect Worker routes, WAF or bot rules, TLS mode, request headers, and Cloudflare-generated response branding. Preserve the proxy state and provide the URL, code, UTC time, and Ray ID to the host or Cloudflare support contact.

The document is 200 but the screenshot is incomplete

Inspect every dependent request, including lazy images and API calls. Increase the capture wait only after identifying the slow dependency; a longer delay cannot fix a 403, DNS error, or JavaScript exception.

FAQ

Does a 502 always mean Cloudflare is down?

No. A branded page often reports an origin response. Use body, headers, Ray ID, and origin logs to classify it.

Should I change DNS during an outage?

Check the status API and collect evidence first. Change DNS only as an authorized, reversible comparison with a known-good origin.

What should I send my hosting provider?

Send the exact URL, UTC time, status code, complete relevant headers, Ray ID, region, sanitized HAR, and direct-origin comparison.

Is a successful landing page enough to declare recovery?

No. Verify CSS, JavaScript, fonts, images, lazy content, and API calls from the previously affected region.

Can ScreenshotNeo diagnose the cause of a Cloudflare outage?

It can provide a repeatable capture and page verdict, but Cloudflare headers, status data, HAR files, and origin logs are still required to identify the failing layer.