Recently I experienced an issue with NPM, I couldn’t install any packages. I found some suggestions on google to upgrade npm but npm install -g npm didn’t work either. After some debugging and searching on npm repo issues, I finally found a temporary solution.

If you need the solution, you can go straight to Solution and come back to read my findings later while npm doing what it needs to do.

At first, when I tried installing packages for a cloned repository. I got following log.

npm ERR! code ERR_SOCKET_TIMEOUT
npm ERR! network Socket timeout
npm ERR! network This is a problem related to network connectivity.
npm ERR! network In most cases you are behind a proxy or have bad network settings.
npm ERR! network 
npm ERR! network If you are behind a proxy, please make sure that the
npm ERR! network 'proxy' config is set properly.  See: 'npm help config'

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/node/.npm/_logs/2023-05-29T10_05_11_383Z-debug-0.log

It looked like I have some network problem. But I could browse npm and go to https://registry.npmjs.org ok. So I didn’t understand why it happened.

I tried to run the command again with more debugging info

npm i -g npm --verbose
npm verb cli /home/sytran/.nvm/versions/node/v18.16.0/bin/node /home/sytran/.nvm/versions/node/
v18.16.0/bin/npm
npm info using npm@9.5.1
npm info using node@v18.16.0
npm verb title npm i npm
npm verb argv "i" "--global" "npm" "--loglevel" "verbose"
npm verb logfile logs-max:10 dir:/home/sytran/.npm/_logs/2023-05-29T10_26_47_469Z-
npm verb logfile /home/sytran/.npm/_logs/2023-05-29T10_26_47_469Z-debug-0.log
^C

And also tailing the log file to quickly identify any issues

tail -f -n 100  /home/sytran/.npm/_logs/2023-05-29T10_26_47_469Z-debug-0.log
0 verbose cli /home/sytran/.nvm/versions/node/v18.16.0/bin/node /home/sytran/.nvm/versions/node/v18.16.0/bin/npm
1 info using npm@9.5.1
2 info using node@v18.16.0
3 timing npm:load:whichnode Completed in 1ms
4 timing config:load:defaults Completed in 2ms
5 timing config:load:file:/home/sytran/.nvm/versions/node/v18.16.0/lib/node_modules/npm/npmrc Completed in 0ms
6 timing config:load:builtin Completed in 0ms
7 timing config:load:cli Completed in 2ms
8 timing config:load:env Completed in 0ms
9 timing config:load:project Completed in 1ms
10 timing config:load:file:/home/sytran/.npmrc Completed in 1ms
11 timing config:load:user Completed in 1ms
12 timing config:load:file:/home/sytran/.nvm/versions/node/v18.16.0/etc/npmrc Completed in 1ms
13 timing config:load:global Completed in 1ms
14 timing config:load:setEnvs Completed in 1ms
15 timing config:load Completed in 8ms
16 timing npm:load:configload Completed in 8ms
17 timing npm:load:mkdirpcache Completed in 0ms
18 timing npm:load:mkdirplogs Completed in 0ms
19 verbose title npm i npm
20 verbose argv "i" "--global" "npm" "--loglevel" "verbose"
21 timing npm:load:setTitle Completed in 1ms
22 timing config:load:flatten Completed in 3ms
23 timing npm:load:display Completed in 5ms
24 verbose logfile logs-max:10 dir:/home/sytran/.npm/_logs/2023-05-29T10_26_47_469Z-
25 verbose logfile /home/sytran/.npm/_logs/2023-05-29T10_26_47_469Z-debug-0.log
26 timing npm:load:logFile Completed in 5ms
27 timing npm:load:timers Completed in 0ms
28 timing npm:load:configScope Completed in 0ms
29 timing npm:load Completed in 20ms
30 timing config:load:flatten Completed in 0ms

Because it took too long freezing, I decided to log everything and let it run. And I just went to swimming pool for the next hour 🏊 🏊

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
$ npm i -g npm -ddd
npm verb cli /home/sytran/.nvm/versions/node/v18.16.0/bin/node /home/sytran/.nvm/versions/node/v18.16.0/bin/npm
npm info using npm@9.5.1
npm info using node@v18.16.0
npm verb title npm i npm
npm verb argv "i" "--global" "npm" "--loglevel" "silly"
npm verb logfile logs-max:10 dir:/home/sytran/.npm/_logs/2023-05-29T10_32_29_127Z-
npm verb logfile /home/sytran/.npm/_logs/2023-05-29T10_32_29_127Z-debug-0.log
npm sill logfile start cleaning logs, removing 
2 files
npm sill logfile done cleaning log files
npm verb type system
npm verb stack FetchError: request to https://registry.npmjs.org/npm failed, reason: connect ETIMEDOUT 2606:4700::6810:1723:443
npm verb stack     at ClientRequest.<anonymous> (/home/sytran/.nvm/versions/node/v18.16.0/lib/node_modules/npm/node_modules/minipass-fetch/lib/index.js:130:14)
npm verb stack     at ClientRequest.emit (node:events:513:28)
npm verb stack     at TLSSocket.socketErrorListener (node:_http_client:502:9)
npm verb stack     at TLSSocket.emit (node:events:525:35)
npm verb stack     at emitErrorNT (node:internal/streams/destroy:151:8)
npm verb stack     at emitErrorCloseNT (node:internal/streams/destroy:116:3)
npm verb stack     at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
npm verb cwd /home/sytran/Work/athena/exchange_service
npm verb Linux 5.15.0-72-generic
npm verb node v18.16.0
npm verb npm  v9.5.1
npm ERR! code ETIMEDOUT
npm ERR! syscall connect
npm ERR! errno ETIMEDOUT
npm ERR! network request to https://registry.npmjs.org/npm failed, reason: connect ETIMEDOUT 2606:4700::6810:1723:443
npm ERR! network This is a problem related to network connectivity.
npm ERR! network In most cases you are behind a proxy or have bad network settings.
npm ERR! network 
npm ERR! network If you are behind a proxy, please make sure that the
npm ERR! network 'proxy' config is set properly.  See: 'npm help config'
npm verb exit 1
npm verb code 1

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/sytran/.npm/_logs/2023-05-29T10_32_29_127Z-debug-0.log

I realised registry.npmjs.org resolved to an IPv6, and that could be the problem. Maybe it was not correct IP. I did a nslookup to confirm.

nslookup registry.npmjs.org
Server:		127.0.0.53
Address:	127.0.0.53#53

Non-authoritative answer:
Name:	registry.npmjs.org
Address: 104.16.26.35
Name:	registry.npmjs.org
Address: 104.16.24.35
Name:	registry.npmjs.org
Address: 104.16.18.35
Name:	registry.npmjs.org
Address: 104.16.21.35
Name:	registry.npmjs.org
Address: 104.16.27.35
Name:	registry.npmjs.org
Address: 104.16.17.35
Name:	registry.npmjs.org
Address: 104.16.23.35
Name:	registry.npmjs.org
Address: 104.16.20.35
Name:	registry.npmjs.org
Address: 104.16.19.35
Name:	registry.npmjs.org
Address: 104.16.22.35
Name:	registry.npmjs.org
Address: 104.16.25.35
Name:	registry.npmjs.org
Address: 104.16.16.35
Name:	registry.npmjs.org
Address: 2606:4700::6810:1423
Name:	registry.npmjs.org
Address: 2606:4700::6810:1123
Name:	registry.npmjs.org
Address: 2606:4700::6810:1523
Name:	registry.npmjs.org
Address: 2606:4700::6810:1b23
Name:	registry.npmjs.org
Address: 2606:4700::6810:1623
Name:	registry.npmjs.org
Address: 2606:4700::6810:1023
Name:	registry.npmjs.org
Address: 2606:4700::6810:1923
Name:	registry.npmjs.org
Address: 2606:4700::6810:1323
Name:	registry.npmjs.org
Address: 2606:4700::6810:1723
Name:	registry.npmjs.org
Address: 2606:4700::6810:1223
Name:	registry.npmjs.org
Address: 2606:4700::6810:1823
Name:	registry.npmjs.org
Address: 2606:4700::6810:1a23

Well, there was not one but many IPv6 ones, so that couldn’t be wrong. But I couldn’t ping any of them.

ping -c 1 2606:4700::6810:1a23
PING 2606:4700::6810:1a23(2606:4700::6810:1a23) 56 data bytes
^C
--- 2606:4700::6810:1a23 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

But I can still ping IPv4 ok.

ping -c 1 104.16.26.35
PING 104.16.26.35 (104.16.26.35) 56(84) bytes of data.
64 bytes from 104.16.26.35: icmp_seq=1 ttl=56 time=29.2 ms

--- 104.16.26.35 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 29.157/29.157/29.157/0.000 ms

At this point, I know I just need to disable the IPv6 DNS. So I just go straight into my /etc/hosts and edit it.

# temporary fix for dns v6 issue. remove later
104.16.26.35    registry.npmjs.org

After that I could install all packages under a minute 😌

But I couldn’t stop there. Searching for NPM IPv6 issue, I found this issue on npm repo. Reading further I found the solution comment.

Solution Link to heading

NPM registry has some IPv4 and IPv6 DNS records, but my ISP cannot resolve IPv6 address. So we need to force NPM to use IPv4 instead. Try npm ping with extra node options as follow.

$ NODE_OPTIONS='--dns-result-order=ipv4first' npm ping registry.npmjs.org
npm notice PING https://registry.npmjs.org/
npm notice PONG 440ms

If the ping success you can install packages with this command

$ NODE_OPTIONS='--dns-result-order=ipv4first' npm install

For longer term. We might need to wait for NPM to add a patch to fallback to IPv4 incase IPv6 doesn’t work. Or change the ISP 😱