
What it means: The server accepted the connection and request, then closed it without sending any response data.
curl -vFree online tool — HTTP header checker: instant results, no signup.
Requests the address and shows the status code and what the server sends back.
net::ERR_EMPTY_RESPONSE is Chromium error -324, defined in net_error_list.h as «The server closed the connection without sending any data.» DNS resolved, the TCP connection (and the TLS handshake, for HTTPS) succeeded, Chrome sent the request, and the other side closed the connection before a single byte of HTTP response came back. There is no status code, because there was no response.
It is not a refused connection (nothing listening gives ERR_CONNECTION_REFUSED), not a reset (a TCP RST gives ERR_CONNECTION_RESET), not a timeout, and not a certificate error. Chrome already retries once when this happens on a reused keep-alive connection, so by the time you see the error, a fresh connection also came back empty.
| Browser | What you see | Most common trigger |
|---|---|---|
| Chrome, Edge | «This page isn't working» and «host didn't send any data.» | The server, or something in front of it, closed the connection on purpose or after a crash |
| Firefox | Its own connection-error page; the Chrome code is not shown | The same empty close |
| Safari | Its own connection-error message | The same empty close |
| curl | curl: (52) Empty reply from server | The same empty close; the quickest way to reproduce it |
Deliberate closes are the most common source. nginx's non-standard code 444 closes a connection without sending a response header, and is often used in a catch-all default_server or in bot-blocking rules; a request whose Host header matches no server_name (for example, after DNS was pointed at a new server that does not know the domain yet) gets an empty response. HAProxy's http-request reject does the same.
Crashes are the other source, when the process that accepted the connection dies before answering: a Node.js, Gunicorn or PHP built-in server exposed directly that crashes or is killed by the OOM killer, or a Docker container whose app listens only on 127.0.0.1 inside the container, which commonly gives an empty reply when the published port is tested from the host. Plain HTTP sent to a TLS-only port (http://example.com:443) is a third: many TLS listeners simply close the connection, while nginx answers with a 400 instead.
A reverse proxy normally converts an empty upstream into an error status, so the browser does not see ERR_EMPTY_RESPONSE. nginx logs upstream prematurely closed connection while reading response header from upstream and returns 502; Cloudflare returns 520, which its documentation describes as the origin dropping the TCP connection before sending response headers. If visitors see ERR_EMPTY_RESPONSE on a proxied site, the empty close comes from the proxy itself (a return 444 rule) or from something between the visitor and the proxy.
# Find deliberate empty closes in nginx
grep -rn 'return 444' /etc/nginx/
# A catch-all that answers unknown hosts with a visible status instead
server {
listen 80 default_server;
listen 443 ssl default_server;
server_name _;
ssl_certificate /etc/nginx/ssl/default.crt;
ssl_certificate_key /etc/nginx/ssl/default.key;
return 421;
}Keep 444 if you want silent drops for scanners, but make sure every real hostname has its own server block.
curl -v https://example.com/ -o /dev/null
# * Empty reply from server
# curl: (52) Empty reply from serverdig +short example.com), then test that server directly: curl -v --resolve example.com:443:203.0.113.10 https://example.com/.return 444 in nginx, http-request reject in HAProxy, or a WAF or rate-limit rule that drops instead of answering.dmesg -T | grep -iE 'killed process|segfault'
journalctl -u myapp --since '-1h'Fix the crash, then put a reverse proxy in front of the app server so future crashes become a visible 502 with a log line.0.0.0.0 inside the container and confirm it with docker exec <container> ss -ltn.Upstream log lines that point here: ERR_EMPTY_RESPONSE fix guide and debugging nginx errors.
Reload once; if the server was restarting, the next request may succeed. Then try another network or mobile data and another browser. If it fails everywhere, the problem is on the server and only the site owner can fix it.
If it fails only on your computer or network, check what sits in the path: a VPN or proxy, or an antivirus with HTTPS or web scanning, can close connections it does not like. Pause it briefly and retry. Also check the address bar: http:// on a port meant for HTTPS, or a typo in a custom port, produces exactly this error. Clearing the browser cache does not help, because nothing was received to cache.
curl -sS -o /dev/null -w '%{http_code} %{size_download}\n' https://example.com/
# 200 18342Any status code means the server is answering again; repeat the test for the exact path and host name that failed, and from a second network. To check the response from outside your own network, use the HTTP status checker.
Refused means the TCP connection was never established because nothing listened on the port. Empty response means the connection was established and the request sent, but the server closed it without replying.
That name probably matches no server_name, so the request lands in a catch-all block that uses nginx return 444. This is common right after DNS was pointed at a new server; add a server block for the name.
Compare the exact URL, host name and headers. A bot or user-agent rule that answers with nginx return 444, or a VPN or antivirus that only filters browser traffic, can affect one client and not the other.
Temporarily, if a crashed or exhausted process was the cause, but the error returns. Find the root cause in dmesg and the application log first.
No. For HTTPS the TLS handshake had already succeeded; the server closed the connection after receiving the request, before sending any response.
Free plan — 10 monitors, checks every 5 min, no card required. Upgrade for 1-minute interval and multi-region monitoring.