Skip to content

Issue: recv() failed (104: Connection reset by peer) while proxying/upgrading WebSocket in NGINX with Socket.IO #5370

Open

Description

@Naveen-Mallow

Describe the bug

We're encountering the following NGINX errors while using it as a reverse proxy to a Node.js server running Socket.IO. These errors occur during WebSocket connections.

1. While proxying upgraded WebSocket connection:

*10088819 recv() failed (104: Connection reset by peer) while proxying upgraded connection, client: <internal-ip>, server: , request: "GET /socket.io/?EIO=4&transport=websocket HTTP/1.1", upstream: "http://127.0.0.1:8080/socket.io/?EIO=4&transport=websocket", host: "<hostname>"

2. While reading response header from upstream:

*13983419 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: <internal-ip>, server: , request: "GET /socket.io/?EIO=4&transport=websocket HTTP/1.1", upstream: "http://127.0.0.1:8080/socket.io/?EIO=4&transport=websocket", host: "<hostname>"

Environment

  • Node.js: 18.x
  • Socket.IO: 4.7.4
  • NGINX: 1.28.0
  • Deployment: NGINX as a reverse proxy to a Node.js server
  • Transport: WebSocket (transport=websocket)
  • Clients: Mobile app (Socket.IO client)

What We’ve Checked

  • These errors consistently occur randomly.
  • Socket.IO server logs do not show any corresponding exceptions or disconnect messages.
  • Other HTTP (non-WebSocket) traffic through NGINX works without issues.
  • No known memory or CPU bottlenecks on the Node.js server.
  • No aggressive timeouts or buffer limits are configured in NGINX.

Current NGINX Configuration

location /socket.io/ {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;

    proxy_pass http://nodes;

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";

    proxy_connect_timeout 75s;
    proxy_send_timeout 75s;
    proxy_read_timeout 75s;
                
    proxy_buffering off;
    proxy_request_buffering off;
}

Questions / Guidance Needed

  1. We’re seeking help to understand and troubleshoot this behavior. Specifically:
  2. What are the common causes of recv() failed (104: Connection reset by peer) in a Socket.IO + NGINX setup, particularly during WebSocket upgrades?
  3. Is it possible for the Socket.IO server to terminate a connection without logging it?
  4. How can we distinguish whether the disconnect is triggered by the client, network, NGINX, or Socket.IO server?
  5. What debugging strategies or additional logging/tracing can help us isolate the root cause?

Additional Context

  • Issue is strictly limited to WebSocket transport.
  • NGINX and Node.js server are hosted on the same machine (127.0.0.1 backend).
  • Client devices are stable and do not indicate network issues at their end.
  • Please let us know what diagnostics or traces from the Socket.IO server we can enable to better trace or isolate this.

Thanks in advance for your help!

Activity

  1. expo20999-ship-it commented on Oct 5, 2025

    @expo20999-ship-it

    Describe the bug

    We're encountering the following NGINX errors while using it as a reverse proxy to a Node.js server running Socket.IO. These errors occur during WebSocket connections.

    1. While proxying upgraded WebSocket connection:

    *10088819 recv() failed (104: Connection reset by peer) while proxying upgraded connection, client: <internal-ip>, server: , request: "GET /socket.io/?EIO=4&transport=websocket HTTP/1.1", upstream: "http://127.0.0.1:8080/socket.io/?EIO=4&transport=websocket", host: "<hostname>"

    2. While reading response header from upstream:

    *13983419 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: <internal-ip>, server: , request: "GET /socket.io/?EIO=4&transport=websocket HTTP/1.1", upstream: "http://127.0.0.1:8080/socket.io/?EIO=4&transport=websocket", host: "<hostname>"

    Environment

    • Node.js: 18.x
    • Socket.IO: 4.7.4
    • NGINX: 1.28.0
    • Deployment: NGINX as a reverse proxy to a Node.js server
    • Transport: WebSocket (transport=websocket)
    • Clients: Mobile app (Socket.IO client)

    What We’ve Checked

    • These errors consistently occur randomly.
    • Socket.IO server logs do not show any corresponding exceptions or disconnect messages.
    • Other HTTP (non-WebSocket) traffic through NGINX works without issues.
    • No known memory or CPU bottlenecks on the Node.js server.
    • No aggressive timeouts or buffer limits are configured in NGINX.

    Current NGINX Configuration

    location /socket.io/ {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
    
        proxy_pass http://nodes;
    
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    
        proxy_connect_timeout 75s;
        proxy_send_timeout 75s;
        proxy_read_timeout 75s;
                    
        proxy_buffering off;
        proxy_request_buffering off;
    }
    

    Questions / Guidance Needed

    1. We’re seeking help to understand and troubleshoot this behavior. Specifically:
    2. What are the common causes of recv() failed (104: Connection reset by peer) in a Socket.IO + NGINX setup, particularly during WebSocket upgrades?
    3. Is it possible for the Socket.IO server to terminate a connection without logging it?
    4. How can we distinguish whether the disconnect is triggered by the client, network, NGINX, or Socket.IO server?
    5. What debugging strategies or additional logging/tracing can help us isolate the root cause?

    Additional Context

    • Issue is strictly limited to WebSocket transport.
    • NGINX and Node.js server are hosted on the same machine (127.0.0.1 backend).
    • Client devices are stable and do not indicate network issues at their end.
    • Please let us know what diagnostics or traces from the Socket.IO server we can enable to better trace or isolate this.

    Thanks in advance for your help!

  2. darrachequesne commented on May 29, 2026

    @darrachequesne
    Member

    @Naveen-Mallow have you found the culprit?

  3. AliMahmoudDev commented on Jun 6, 2026

    @AliMahmoudDev

    The 104: Connection reset by peer errors from NGINX are normal when a client drops its connection (tab close, network switch, mobile sleep). NGINX logs them because it tries to forward data to an upstream that has already disconnected on the client side. The fact that Socket.IO server logs show no corresponding exceptions or disconnect events is the more interesting part — it means the server-side socket cleanup might not be propagating correctly through the proxy layer.

    For debugging, try adding io.engine.on("connection_error", (err) => console.log("engine connection_error:", err)) and io.on("disconnect", (reason, socket) => console.log("disconnect:", reason, socket.id)) to see if the disconnect is reaching your app at all. You can also check netstat -anp | grep 8080 during the issue to see if there are sockets stuck in CLOSE_WAIT, which would confirm the server process isn"t cleaning up properly.

    Also worth noting: your proxy_read_timeout of 75s might be too short for idle WebSocket connections. When there is no data flowing, NGINX will close the proxy connection after 75s of silence, generating exactly this error. Consider bumping it to something like 86400 for WebSocket connections, or use a separate location block for /socket.io/ with much longer timeouts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions