Browser ERR_EMPTY_RESPONSE — Server Closed Without Data
Diagnose ERR_EMPTY_RESPONSE when the server accepts a connection then closes it without sending an HTTP response, covering crashes and proxy resets.
Symptoms
- ERR_EMPTY_RESPONSE when loading a page
- The server accepts the TCP connection but sends nothing back
- It fails intermittently and clears after a restart
Possible causes
- The application crashed while handling the request
- A reverse proxy reset the connection before the backend replied
- The backend sent an invalid or truncated HTTP response
- A port is opened by a process other than the web server
Diagnosis steps
Check server logs at the moment of the request
Interpretation
A crash, unhandled exception, or abrupt exit correlates with the empty response.
Hit the backend directly, bypassing the proxy
curl -v http://127.0.0.1:8080/Interpretation
If the backend responds and only the proxy fails, the proxy reset the connection.
Verify what is listening on the port
Interpretation
A wrong process bound to the port can accept then drop the connection without an HTTP reply.
Root cause
ERR_EMPTY_RESPONSE means the TCP connection succeeded but closed before any HTTP response bytes arrived. The listener was reachable, so the problem is after accept: the handler crashed, the proxy aborted, or a non-HTTP process held the port and closed without replying.
Fix
Fix the crash or exception in the request handler and add a top-level error handler so failures still produce a response. On the proxy, raise the upstream timeout and check for resets. Ensure the correct process owns the port, and add health checks so a crashed backend is restarted rather than left accepting and dropping connections.
Verify the fix
Reload the page repeatedly; the response arrives with a valid status, and server logs show a completed request instead of an abrupt disconnect.
Symptoms
The browser reports ERR_EMPTY_RESPONSE: the connection opened and then closed with no data. Sometimes a restart fixes it temporarily, which points at a crashed worker or a stale proxy connection.
Diagnosis
Correlate with backend logs and test the backend directly:
curl -v http://127.0.0.1:8080/ # bypass the proxy
ss -ltnp | grep 8080 # confirm the owner
If only the proxied path fails, the proxy reset the upstream connection.
Fix
Ensure every request produces a response, even on error:
process.on('uncaughtException', (err) => {
console.error(err);
});
Raise proxy read timeouts and add a supervisor that restarts crashed processes.
Verification
Reload the page several times; each request returns a valid HTTP status and the access log records completion, with no empty-response errors.
Where the Bytes Go Missing
An empty response differs from a timeout and from a connection refusal, and that difference narrows the cause quickly. A refusal means nothing listened; a timeout means packets were dropped; an empty response means a listener accepted then closed. That usually points at the process dying mid-handler, at a reverse proxy whose upstream timeout fired first, or at the wrong service bound to the port. Checking whether the failure is reproducible only through the proxy is the fastest split, because a direct backend success localises the fault to the proxy layer rather than the application.