nodejs / help

:sparkles: Need help with Node.js? File an Issue here. :rocket:
1.44k stars 276 forks source link

Very strange issue with native fetch only on cloud hosts but node-fetch works #4357

Closed ptdev closed 3 months ago

ptdev commented 3 months ago

Details

Hi,

I came across a very weird problem that I've been trying to debug for a few days now but without success so I was wondering if anybody here has come across something similar or can try the sample code on their end.

The issue arose during development of a Nuxtjs app, but I've managed to pinpoint the issue to node's fetch.

I have made this basic sample code that shows the issue.

Now the issue is: When I run it on my local workstation (MacOS) it works correctly whether I use Node's native fetch or node-fetch.

But, when I place this file on a cloud host (tried Hetzner, DigitalOcean and AWS), it only works when I use node-fetch.

If I try to use the native fetch from node, the request hangs for a long time and then gives out this error:

# node test.mjs

node:internal/deps/undici/undici:12345
    Error.captureStackTrace(err, this);
          ^

TypeError: fetch failed
    at node:internal/deps/undici/undici:12345:11
    at async loadTAReviews (file:///root/test/test.mjs:53:22)
    at async file:///root/test/test.mjs:61:13 {
  cause: Error: read ETIMEDOUT
      at TLSWrap.onStreamRead (node:internal/stream_base_commons:217:20) {
    errno: -110,
    code: 'ETIMEDOUT',
    syscall: 'read'
  }
}

If I then npm install node-fetch and uncomment the node-fetch import from the sample, then the request works correctly and the request goes through almost immediately.

I'm using the same node versions on both workstation and all cloud hosts.

I've deployed new servers on hetzner, digitalocean and AWS with default configurations to rule out any misconfigurations on our existing servers but the behavior is the same everywhere.

If anybody could try to run this on their end or knows what can be causing this I would be greatly apreciated!

I've run out of things to check and have no idea how this is working both ways on a local MacOS but not on a production server.

Cheers.

Node.js version

Node.js v20.11.1

Example code

test.mjs

https://pastebin.com/Ua3cRaUi

Reproduction steps:

Run with native fetch:

node test.mjs

Then to test with node-fetch just uncomment the import from the top of the test.mjs and run it again

Operating system

On my local workstation: MacOS Sonoma 14.2.1 On cloud servers: Usually latest Debian (v12) but also tried Ubuntu

Scope

code

Module and version

Not applicable.

ptdev commented 3 months ago

Sorry I closed this issue by mistake, the issue is still present. Reopening

ptdev commented 3 months ago

Hi again,

After many tries I've finally figured out what was causing this issue.

Noticed that node-fetch would send a user agent string of "node-fetch/v2.0" so I added that string as a header and the native fetch began to work. I then changed the user agent a few more times and came to the conclusion that apparently this server/endpoint is checking for a "fetch" string in the user agent, otherwise I get the error above.

Still weird why it worked on local workstations without the user agent header and not on any cloud host I've tried but nevertheless, the issue appears fixed by adding it.

Closing