I found the answer to this problem already and just want to document my finding.
In one of my recent project, I found that a port would not be shown as being used in netstat, but when my project tried to use the port, an error would be thrown.
For example, let's say I want to use port 53000:
netstat -ano | findstr :53000
Nothing would be shown, but if I attempted to use the port in Node.js, a permission error will be thrown.
It turned out that things such as Hyper-V, Docker, etc would reserve a range of ports. To find out the ranges of ports reserved, do the following:
netsh interface ipv4 show excludedportrange protocol=tcp
In my case, I would see something like this:
Protocol tcp Port Exclusion Ranges
Start Port End Port
---------- --------
49805 49904
50000 50059 *
50060 50159
50160 50259
50360 50459
50870 50969
50970 51069
51070 51169
51270 51369
52353 52452
52453 52552
52553 52652
52653 52752
52853 52952
52953 53052
53053 53152
53324 53423
56247 56346
56347 56446
56547 56646
56647 56746
* - Administered port exclusions.
To fix my problem, I can:
netsh int ipv4 add excludedportrange protocol=tcp startport=53000 numberofports=1
(as administrator)