Node.js / NPM on IPv6-only servers

Example of this issue

When running npm or other Node.JS tools on an IPv6-only server, you may see an error message like the following:

npm ERR! FetchError: request to failed, reason: connect ECONNREFUSED

By default Node will attempt to use IPv4 to connect to external services. On our IPv6-only servers, this will fail, and you will see a message like the above.

Working around this issue

One option to work around this issue is to use tnat64. This will wrap another application, intercept any connections to IPv4 hosts, and redirect them through our NAT64 service.

You can install it like so:

# apt install tnat64

To use tnat64, you simply pass it the command you originally wanted to run, for example:

$ tnat64 npm install express

You can also run your shell under tnat64, to then wrap every application you run afterwards, for example:

$ tnat64 bash
$ npm install express

Setting up an alias for convenience

To make this easier, you could set up an alias which will automatically run tnat64 npm whenever you run npm.

On a server using a standard bash configuration, you can set this up by adding it to your .bash_aliases file.

For example:

echo 'alias npm="tnat64 npm"' >> ~/.bash_aliases
source ~/.bash_aliases

Alternative workaround using /etc/hosts

An alternative option is to hardcode the relevant IPv6 addresses in /etc/hosts. This will force Node to connect over IPv6, and ignore the IPv4 addresses present in DNS.

For example, you could fetch the IPv6 address of like so:

$ getent ahosts | head -1
2606:4700::6810:1b23 STREAM

You can then put this address into your hosts file, eg:

# echo "2606:4700::6810:1b23" >> /etc/hosts

This would then let you run NPM with no wrapper, eg:

$ npm install express

Please note that this may later cause issues if the service changes IP address, as your server will ignore DNS changes for this domain. Therefore, we typically recommend avoiding this method where possible.