← Glossary / Empty Response Body

What is Empty Response Body?

Empty response body occurs when a server accepts a TCP connection and returns HTTP headers (often a 200 OK), but drops the connection before transmitting any payload bytes. For scraping pipelines, it is a notoriously difficult failure mode to debug because the network layer reports success while the extraction layer starves. It usually indicates a silent WAF intervention, an upstream timeout, or a malformed request header triggering a stealth drop.

Scraping ErrorsWAF Stealth DropTCP ResetPipeline StarvationDebugging
// 02 — definitions

Headers arrive,
bytes don't.

Why servers pretend to fulfill a request only to sever the connection at the payload layer, and how to detect it.

Ask a DataFlirt engineer →

TL;DR

An empty response body is a stealth anti-bot tactic or a severe upstream failure where the HTTP status is 200 OK but the payload is zero bytes (or the connection resets mid-flight). It breaks naive scrapers that assume a 200 status guarantees a parsable DOM, leading to silent null-field pollution in downstream datasets.

01Definition & structure
An empty response body happens when an HTTP client successfully establishes a TCP connection and receives response headers, but the server closes the connection before sending any actual content. In scraping, this typically manifests as a 200 OK status code paired with a Content-Length: 0 header, or a chunked transfer that terminates immediately. Because the HTTP status indicates success, naive HTTP clients (like requests or axios) will not throw a network error, passing an empty string to the JSON parser or HTML parser, which then crashes.
02How it works in practice
When a WAF (Web Application Firewall) detects a bot via TLS fingerprinting or IP reputation, it has a choice: return a 403, return a CAPTCHA, or silently drop the request. Returning a 200 OK with no body is a form of tarpitting. It forces the scraper to consume the response, pass it to the extraction logic, and fail downstream. This obscures the fact that a block occurred, making it harder for the scraper operator to realize their proxy or fingerprint is burned.
03The silent data loss problem
The most dangerous aspect of an empty response body is silent data loss. If your pipeline is configured to ignore parsing errors and continue crawling, a stealth block will result in thousands of "successful" requests that yield zero data. You end up writing empty JSON objects or null values to your database. By the time the data engineering team notices the drop in data volume, the target may have updated their site, making backfilling impossible.
04How DataFlirt handles it
We do not trust HTTP status codes. Every response in a DataFlirt pipeline passes through a schema validation gate. If a request returns a 200 OK but the extracted record is empty, the system flags it as a stealth block. The proxy IP is temporarily benched, the TLS fingerprint is rotated, and the request is pushed back into the retry queue with exponential backoff. This ensures that empty responses never pollute the final dataset.
05Edge case: The Accept-Encoding trap
Sometimes an empty response is entirely your fault. If your scraper sends Accept-Encoding: gzip, deflate, br to mimic a browser, but your underlying HTTP client doesn't actually support Brotli (br) decompression, the client may silently fail to decode the payload and return an empty string to your application. Always ensure your HTTP client's capabilities match the headers you are spoofing.
// 03 — the detection model

When is empty
actually an error?

Not all empty bodies are errors — HEAD requests and 204 No Content responses are valid. DataFlirt's pipeline validates payload presence against expected schema density to catch stealth drops.

Payload starvation rate = S = responses_empty / responses_200_ok
S > 0.01 on a GET endpoint usually indicates a silent WAF block. DataFlirt Pipeline Telemetry
Expected byte threshold = Bmin = μhistorical − (3 × σhistorical)
Responses below B_min trigger an automatic quarantine workflow. Extraction Validation Layer
DataFlirt retry budget = R = base_delay × 2attempt + jitter
Exponential backoff applied specifically to zero-byte 200s. Internal Scheduler SLO
// 04 — pipeline trace

A silent drop
at the edge.

A standard Python requests script hitting a protected endpoint. The WAF identifies the bot via JA3 but chooses to tarpit rather than issue a 403 Forbidden.

Python/requestsWAF tarpitTCP RST
edge.dataflirt.io — live
CAPTURED
// outbound request
GET /api/v1/inventory HTTP/1.1
Host: target.com
User-Agent: python-requests/2.31.0

// inbound headers (fast)
HTTP/1.1 200 OK
Server: cloudflare
Content-Type: application/json
Transfer-Encoding: chunked

// payload read phase
read(chunk) -> Timeout (30000ms)
connection.status: RST_STREAM
response.text: ""
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

// pipeline outcome
extraction.status: FAILED (null fields)
// 05 — root causes

Why the server
goes quiet.

Ranked by frequency across DataFlirt's telemetry. Silent WAF drops are the primary culprit, designed specifically to waste scraper compute cycles rather than failing fast.

SAMPLE SIZE ·  ·  ·  ·    1.8M empty 200s
WINDOW ·  ·  ·  ·  ·  ·   30d trailing
UPDATED ·  ·  ·  ·  ·  ·  2026-05-19
01

WAF Stealth Drop (Tarpitting)

~45% of cases · WAF identifies bot, holds connection open, sends nothing
02

Upstream Gateway Timeout

~25% of cases · Edge server (502/504 masked as 200) loses origin connection
03

Malformed Accept-Encoding

~15% of cases · Client claims Brotli/Gzip support but fails to decode
04

Headless Browser Crash

~10% of cases · Target page OOMs the Chromium instance before DOM serialization
05

API Rate Limit (Undocumented)

~5% of cases · Backend returns empty 200 instead of 429 to shed load
// 06 — DataFlirt's mitigation

Trust the schema,

never the HTTP status code.

Naive pipelines log a 200 OK as a success and move on, pushing empty records into the data warehouse. DataFlirt decouples network success from extraction success. Every response is evaluated against a byte-size heuristic and a strict schema contract. If a 200 OK yields zero extracted fields, the proxy session is burned, the fingerprint is rotated, and the request is requeued. We treat empty 200s as hostile 403s.

Extraction validation trace

How DataFlirt's edge handles a stealth-dropped 200 OK response.

request.id req-88f2-empty
network.status 200 OK
payload.bytes 0
schema.completeness 0.0
action.taken quarantine_record
proxy.action burn_ip
retry.status queued_new_fingerprint

Stay ahead of the pipeline

Data engineering
intel, weekly.

Anti-bot shifts, scraping infrastructure updates, dataset delivery patterns, and business outcomes from our pipelines. Short, technical, no fluff.

// 07 — FAQ

Common
questions.

Common questions about debugging empty responses, WAF tarpitting, and how to prevent silent data loss in your pipelines.

Ask us directly →
Why would a server return a 200 OK with no data instead of a 403? +
To waste your resources. A 403 Forbidden tells you immediately to rotate proxies and try again. An empty 200 forces your scraper to parse the response, fail at the extraction layer, and spend developer time debugging. It increases your operational cost and slows down your crawl rate.
How do I fix an empty response body error? +
First, check your headers. Ensure your Accept-Encoding matches what your HTTP client can actually decompress. If your headers are perfect and you still get empty bodies, you are likely being fingerprinted and stealth-dropped. You need to rotate your JA3/JA4 TLS signature and switch to a cleaner IP.
Is an empty response always a bot mitigation tactic? +
No. It can be a legitimate upstream failure. If a reverse proxy (like Nginx) starts sending chunked headers to the client before the backend application server crashes, the connection will close with zero payload bytes. However, if it only happens to your scraper and not your browser, it's a block.
How does DataFlirt handle empty responses at scale? +
We classify them as "stealth blocks." Our edge workers monitor the byte-yield of all 200 OK responses. If a specific target starts returning empty bodies, our system automatically shifts the routing profile to higher-tier residential IPs, rotates TLS fingerprints, and alerts the pipeline operator.
What is the legal implication of bypassing a stealth block? +
An empty response is a technical countermeasure, not a legal boundary. However, repeatedly hammering an endpoint that is intentionally dropping your connections can be construed as abusive. We back off exponentially to respect target infrastructure while we re-calibrate the scraper's identity profile.
Why does my browser see the data but my scraper gets an empty body? +
Your scraper is failing a pre-flight check. The server is inspecting your TLS Client Hello or HTTP/2 frame order, flagging it as non-browser, and returning an empty body before the application layer even processes the route. Your scraper's network signature is giving you away.
$ dataflirt scope --new-project --target=empty-response-body READY

Tell us what
to extract.
We do the rest.

20-minute scoping call. Pilot dataset within the week. Production within two. Whether you need a one-off catalogue dump or a continuous feed across millions of records — we scope, build, and operate the pipeline.

hello@dataflirt.com  ·  Bengaluru  ·  IST  ·  typical reply < 4h