undici: `UND_ERR_SOCKET` in fetch

Sometimes fetch ends up with exception:

{
  cause: {
    name: "SocketError",
    code: "UND_ERR_SOCKET",
    socket: {
      localAddress: "192.168.1.33",
      localPort: 12345,
      remoteAddress: "X.Y.Z.W",
      remotePort: 443,
      remoteFamily: "IPv4",
      timeout: undefined,
      bytesWritten: 651,
      bytesRead: 441,
    },
    message: "other side closed",
    stack: "SocketError: other side closed\n    at TLSSocket.onSocketEnd (node:internal/deps/undici/undici:9499:26)\n    at TLSSocket.emit (node:events:524:35)\n    at endReadableNT (node:internal/streams/readable:1359:12)\n    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)"
  },
  message: "fetch failed",
  stack: "TypeError: fetch failed\n    at Object.fetch (node:internal/deps/undici/undici:12789:11)\n    at async Object.xyzFunc..."
}

Unfortunately, we don’t have a reproducible code, because of complexity of application, the initial fetch requests work, but after making some further fetch we sporadically get the error. Do you have any suggestions? Have tried all workaround found in internet, but nothing worked. The exact request which fails with node fetch, works from postman.

( Windows 11, tested results below with v19.6, however same issue happens in 18.14)

About this issue

  • Original URL
  • State: open
  • Created a year ago
  • Reactions: 4
  • Comments: 16 (7 by maintainers)

Most upvoted comments

A few things:

  1. The error listed at the top literally is saying that the connection was cut. It’s TCP, and a connection can be broken for any reason, even ones unrelated to fetch().
  2. usually it’s due to configuring the various timeouts we have by default. Change the settings and experiment in your system.
  3. HTTP at scale it’s hard.

If we have a reproduction, we can fix it. Please give us:

  1. a server
  2. a client program that passes with got/node-fetch/http.request
  3. a client program that errors with undici fetch()

We will investigate this.

Alternatively, somebody would have to contract one of us to dig into their private codebase and identify the problem. Note that it is extremely likely it is related to some other piece of your infrastructure cutting the connection for whatever reason.

This happens when the socket is closed before receiving a status code (more or less). I believe it’s been a known ‘issue’ for a while now.

repro
import { fetch } from 'undici'
import { createServer } from 'http'
import { once } from 'events'

const server = createServer((req, res) => {
  res.socket.end()
}).listen(0)

await once(server, 'listening')

await fetch(`http://localhost:${server.address().port}`)

Hey fellow undici users !

  • In September we removed node-fetch from an app to use internal node fetch.

    • We detected some UND_ERR_SOCKET errors related to API calls using fetch that we didn’t have before.
    • Back then, I found this issue and, as the app was running on Node v18.6.0, I didn’t add a comment because @mcollina pointed out that the fetch implementation might be buggy in v18.
  • In October, we migrated Node to the latest LTS and are now using Node v20.10.0.

    • We were hopeful, but the problem persists
    • To assert that the problem was on the client-side of the call, I polyfilled fetch globally with node-fetch v3
      • no more errors

Do you have any ideas ?