Skip to content

fix(http): handle socket errors to prevent EPIPE crashes#10561

Closed
cyphercodes wants to merge 2 commits intoaxios:v1.xfrom
cyphercodes:fix/epipe-socket-error
Closed

fix(http): handle socket errors to prevent EPIPE crashes#10561
cyphercodes wants to merge 2 commits intoaxios:v1.xfrom
cyphercodes:fix/epipe-socket-error

Conversation

@cyphercodes
Copy link
Copy Markdown
Contributor

@cyphercodes cyphercodes commented Mar 25, 2026

Problem

Failed requests can sometimes crash the Node.js process with EPIPE error when the server destroys the socket while the request body is still being written.

This issue was reported in #10558 where the following uncaught exception occurs:

Error: write EPIPE
    at WriteWrap.onWriteComplete [as oncomplete] (node:internal/stream_base_commons:87:19)

Solution

Add an error event handler to the request socket in the HTTP adapter. This catches socket-level errors (like EPIPE, ECONNRESET) that occur after the socket is assigned but might not be caught by the request error handler alone.

Changes

  • Added socket error handler in lib/adapters/http.js that rejects the promise with an AxiosError when socket errors occur

Testing

Impact

Critical bug fix - Prevents Node.js process crashes in production environments when dealing with unreliable connections or servers that close connections unexpectedly.

Fixes #10558


Summary by cubic

Handle socket errors in the Node.js HTTP adapter to prevent EPIPE/ECONNRESET crashes. Use socket.once to avoid listener leaks on keep‑alive sockets; requests now reject with AxiosError instead of crashing.

Description

Docs

  • No public API changes
  • Note: socket errors (e.g., EPIPE, ECONNRESET) surface as AxiosError rejections

Testing

  • No new tests
  • Manually verified with the Failed requests can sometimes crash the Node.js process with EPIPE. #10558 repro; request rejects and process doesn’t crash
  • Recommend regression tests:
    • Server closes socket mid-write → assert rejection with AxiosError carrying code EPIPE/ECONNRESET
    • Keep‑alive reuse → ensure no listener accumulation (e.g., listener count or process warnings)

Written for commit c13c943. Summary will update on new commits.

Add error event handler to the request socket to catch errors like EPIPE
that can crash the Node.js process when the connection is destroyed
while the request body is still being written.

Fixes axios#10558
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file

Confidence score: 3/5

  • There is a concrete medium-severity risk in lib/adapters/http.js: a per-request socket.on('error') listener is not removed, which can accumulate on keep-alive socket reuse.
  • Given the 6/10 severity with high confidence (9/10), this is likely to cause runtime warnings and potential memory/performance degradation under sustained traffic, so merge risk is moderate.
  • Pay close attention to lib/adapters/http.js - ensure socket error listeners are detached or otherwise bounded per request to prevent listener buildup.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="lib/adapters/http.js">

<violation number="1" location="lib/adapters/http.js:878">
P2: Per-request `socket.on('error')` listener is never detached, causing listener accumulation on reused keep-alive sockets.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread lib/adapters/http.js Outdated
Change socket.on('error') to socket.once('error') in handleRequestSocket
to prevent listener accumulation on reused keep-alive sockets.

Fixes axios#10561
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="lib/adapters/http.js">

<violation number="1" location="lib/adapters/http.js:879">
P2: `socket.once('error')` is added per request on reused keep-alive sockets but never removed on successful completion, so listeners can accumulate until an error occurs.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread lib/adapters/http.js

// Handle socket errors to prevent uncaught exceptions (e.g., EPIPE)
// Use once() to avoid listener accumulation on reused keep-alive sockets
socket.once('error', function handleSocketError(err) {
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: socket.once('error') is added per request on reused keep-alive sockets but never removed on successful completion, so listeners can accumulate until an error occurs.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At lib/adapters/http.js, line 879:

<comment>`socket.once('error')` is added per request on reused keep-alive sockets but never removed on successful completion, so listeners can accumulate until an error occurs.</comment>

<file context>
@@ -875,7 +875,8 @@ export default isHttpAdapterSupported &&
         // Handle socket errors to prevent uncaught exceptions (e.g., EPIPE)
-        socket.on('error', function handleSocketError(err) {
+        // Use once() to avoid listener accumulation on reused keep-alive sockets
+        socket.once('error', function handleSocketError(err) {
           reject(AxiosError.from(err, null, config, req));
         });
</file context>
Fix with Cubic

@jasonsaayman
Copy link
Copy Markdown
Member

Closing in favour of #10662

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Failed requests can sometimes crash the Node.js process with EPIPE.

2 participants