← Debugging Guides

阅读中文版本

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.

intermediatedebuggingbrowserhttpproxy

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.