NodeJS ETIMEDOUT, ESOCKETTIMEDOUT, ENOTFOUND

Posted on May 1, 2020 at 12:48 am

While using request package with a NodeJS script I noticed it was causing a lot of errors like ETIMEDOUT, ESOCKETTIMEDOUT and also getaddrinfo ENOTFOUND after some HTTP requests on the same URL. That was very strange because the remote URL was working correctly…

So I started to analyze a few things and I noticed that NodeJS request package was VERY slow to perform the DNS resolution of some hosts (e.g github.com), the bottleneck was infact in the DNS resolution part (gathering of the IP address of the URL’s host).

Looks like that if the DNS query takes long-ish time, the requests will block on the DNS resolution phase and timeout-errors, like ETIMEDOUT, will be displayed. So I tried a few workarounds to resolve this situation until I found the correct one:

1) Disable TLS validation

This option will disable TLS validation (keep in mind this is insecure):

#!/usr/bin/env node
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";

Details for NODE_TLS_REJECT_UNAUTHORIZED can be found here:

https://nodejs.org/api/cli.html#cli_node_tls_reject_unauthorized_value

This workaround didn’t work.

2) Increase UV_THREADPOOL_SIZE value

This should increase worker threads used to perform DNS resolutions:

#!/usr/bin/env node
process.env.UV_THREADPOOL_SIZE = 128;
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";

Details for UV_THREADPOOL_SIZE can be found here:

https://github.com/nodejs/node/issues/22468#issuecomment-416950146

This workaround didn’t work.

3) Increase request() default timeout

This option will increase the default NodeJs request() timeout:

var options = {
    url: 'https://github.com/...',
    timeout: 120000
}
 
request.get(options,function(err, res, body)[...]

Details for the timeout parameter can be found here:

https://github.com/request/request#user-content-requestoptions-callback

This workaround didn’t work.

4) Disable strictSSL on NodeJS request()

This option will disable the requirement of a valid SSL certificate:

var options = {
    url: 'https://github.com/',
    timeout: 120000,
    strictSSL: false
}
 
request.get(options,function(err, res, body)[...]

Details for the strictSSL parameter can be found here:

https://github.com/request/request#user-content-requestoptions-callback

This workaround didn’t work.

5) Use Google DNS on /etc/resolv.conf

This option will use Google Public DNS (known to be very fast) to speed-up DNS resolutions.

Edit /etc/resolv.conf and remove all lines that contain “nameserver”.

Then add the two Google Public DNS’s IP addresses:

nameserver 8.8.8.8
nameserver 8.8.4.4

You can read more information about Google Public DNS here:

https://developers.google.com/speed/public-dns

This worked perfectly!

6) Add host IP address on /etc/hosts

This option will add on /etc/hosts the IP address of the domain name.

In this case DNS resolution is not performed because data is gathered from /etc/hosts file.

Edit /etc/hosts and add this line (syntax is “ipaddress domain”):

140.82.118.4 github.com

It has the maximum priority, meaning this file is preferred ahead of any other name system.

On the file /etc/nsswitch.conf you can check the order of name resolution.

More information can be found here: https://linux.die.net/man/5/hosts

This worked perfectly!

Updated on May 2, 2020 at 12:02 am

Receive updates via email

Other Posts

Updated Posts