Windows Setup

Configure Windows Firewall for Node.js Servers

Tech Setup6 min readUpdated October 20, 2026
TS

Tech Setup

Published September 12, 2026 · Editorial policy

Configure Windows Firewall for Node.js Servers

Running a Node.js API development server locally on Windows often means other devices on your local network—or a WSL2 instance—suddenly can't reach it. By default, the Windows Defender Firewall blocks all unsolicited inbound TCP connections, leaving you staring at an ERR_CONNECTION_REFUSED error in your browser. You will configure inbound firewall rules specifically for Node.js using both PowerShell and the graphical interface, ensuring your development endpoints are reachable without disabling your system security entirely.

Quick TL;DR: The PowerShell One-Liner

If you need your local Node.js server accessible on port 3000 right now, open an elevated PowerShell prompt and run this command:

New-NetFirewallRule -DisplayName "Node.js Dev Server (Port 3000)" -Direction Inbound -LocalPort 3000 -Protocol TCP -Action Allow

Expected output:

Name                  : {guid-string-here}
DisplayName           : Node.js Dev Server (Port 3000)
Description           :
DisplayGroup          :
Group                 :
Enabled               : True
Profile               : All
Direction             : Inbound
Action                : Allow
EdgeTraversalPolicy   : Deny
Protocol              : TCP
LocalPort             : 3000
RemotePort            : Any
LocalAddress          : Any
RemoteAddress         : Any
GatewayBMAddress      : Any
SourceAddress         : Any
ProtectedInfo         : Shaded
Profile               : Domain, Private, Public,

This immediately opens port 3000 for TCP traffic across all network profiles. If your application runs on 8080, 5000, or a custom environment variable, swap out the -LocalPort value accordingly.

Why Node.js Triggers the Firewall Prompt

When you execute node server.js or npm run dev for the first time, Windows Defender Firewall frequently pops up a dialog asking if you want to allow Node.js to communicate on networks.

Windows Security Alert
Windows Defender Firewall has blocked some features of this app on all public and private networks.
Name: Node.js JavaScript Runtime
Publisher: Joyent, Inc

If you click "Cancel" or if your corporate group policy suppresses these prompts, Windows creates an implicit block rule for the underlying executable: C:\Program Files\nodejs\node.exe.

Furthermore, Node.js applications frequently spawn child processes, use worker threads, or get updated via Node Version Manager (NVM). When you switch from Node.js v18 to v20 using NVM for Windows, the absolute path to your node.exe changes (e.g., from C:\Users\username\AppData\Roaming\nvm\v18.16.0\node.exe to v20.5.0). Generic firewall rules tied to a specific file path instantly break because the binary has moved.

To build a reliable local development environment, you must choose between scoping rules by network port or scoping them by executable path, keeping your toolchain updates in mind.

Creating a Port-Based Rule via PowerShell

Scoping firewall rules by port is the most resilient approach for developers who frequently switch Node versions or manage multiple projects running on different ports.

Open PowerShell as Administrator and run the following script to create a rule for a standard Express or Fastify server running on port 3000:

New-NetFirewallRule `
  -DisplayName "Node.js Local Development" `
  -Direction Inbound `
  -Protocol TCP `
  -LocalPort 3000 `
  -Action Allow `
  -Profile Private

Notice the -Profile Private flag. This ensures your server is only exposed when connected to your home or office Wi-Fi network. If you connect to a public hotspot at a coffee shop, Windows automatically switches the network profile to Public, instantly disabling this rule and protecting your machine.

If your workflow involves a frontend dev server (like Vite on 5173) and a backend API (like Express on 5000), you can pass an array of ports to the -LocalPort parameter:

New-NetFirewallRule `
  -DisplayName "Fullstack Node.js Suite" `
  -Direction Inbound `
  -Protocol TCP `
  -LocalPort 3000, 5000, 5173 `
  -Action Allow `
  -Profile Private

Creating an Executable-Based Rule via the GUI

If you prefer scoping your firewall rules to the Node.js binary itself—preventing other applications from hijacking your designated ports—you can configure the rule using the Windows Defender Firewall with Advanced Security interface.

  1. Press Win + R, type wf.msc, and press Enter.
  2. In the left-hand pane, click on Inbound Rules.
  3. In the right-hand Actions pane, click New Rule...
  4. Select Program and click Next.
  5. Select This program path and browse to your node.exe file.
    • Standard installation: C:\Program Files\nodejs\node.exe
    • NVM for Windows: C:\Users\<YourUsername>\AppData\Roaming\nvm\v<version>\node.exe
  6. Select Allow the connection and click Next.
  7. Check Domain and Private, but leave Public unchecked for security. Click Next.
  8. Name the rule something descriptive like Node.js Runtime (NVM v20) and click Finish.

Managing NVM-Specific Paths

Because NVM for Windows stores binaries in your user profile directory under version-specific folders, an executable-based rule tied to v18.16.0 will fail the moment you run nvm use 20.5.0.

If you use NVM, either stick to Port-Based Rules (which care about the network socket, not the binary path) or update your executable rule path every time you perform a major Node upgrade. Alternatively, you can create a rule pointing to the NVM symbolic link directory if your system environment variables expose it consistently, though port-based scoping remains the industry recommendation for local JS development.

Configuring Windows Subsystem for Linux (WSL2) Networking

If you run your Node.js servers inside a WSL2 distribution (like Ubuntu on Windows), Windows Firewall treats WSL2 as a separate external network interface. By default, WSL2 uses a Network Address Translation (NAT) virtual switch, meaning traffic from your Windows host can reach WSL2, but external network devices cannot reach WSL2 without explicit port proxying.

When you run node app.js inside WSL2 on port 3000, you can access it in your Windows browser via http://localhost:3000 because WSL2 automatically mirrors localhost ports. However, physical devices on your local network (like your phone for mobile testing) cannot access http://<windows-ip>:3000 out of the box.

To expose a WSL2 Node.js server to your local network, run the following command in an Administrator PowerShell prompt on the Windows host:

netsh interface portproxy add v4tov4 listenport=3000 listenaddress=0.0.0.0 connectport=3000 connectaddress=<WSL_IP_ADDRESS>

To find your current WSL2 IP address dynamically, run this command inside your WSL terminal:

hostname -I | awk '{print $1}'

Once the port proxy is active, you must also create a Windows Firewall rule to allow inbound traffic on that port to hit the host's proxy listener:

New-NetFirewallRule -DisplayName "WSL2 Node Port Proxy 3000" -Direction Inbound -LocalPort 3000 -Protocol TCP -Action Allow

To view all active port proxies currently configured on your Windows machine, run:

netsh interface portproxy show v4tov4

To remove the proxy rule when you are finished testing, use:

netsh interface portproxy delete v4tov4 listenport=3000 listenaddress=0.0.0.0

Verifying and Troubleshooting Your Firewall Rules

After applying your firewall configuration, verify that the rule is active and intercepting traffic correctly.

Checking Rule Status via PowerShell

Run this command to filter and display your newly created rule:

Get-NetFirewallRule -DisplayName "*Node*" | Get-NetFirewallPortFilter

Expected output structure:

Protocol LocalPort RemotePort Program
-------- spaz      --------- -------
6        3000      Any       Any

If This Doesn't Work: Common Failure Points

Even with a valid firewall rule, connection attempts often fail due to three common oversights in Node.js development configurations:

  1. Binding to 127.0.0.1 instead of 0.0.0.0: If your Express app initializes with app.listen(3000, '127.0.0.1') or simply app.listen(3000), Node binds exclusively to the local loopback interface. External network requests and WSL2 proxies cannot reach it. Change your server initialization to bind to all interfaces:

    const PORT = process.env.PORT || 3000;
    app.listen(PORT, '0.0.0.0', () => {
      console.log(`Server running on port ${PORT}`);
    });
    
  2. Active VPN Clients: Corporate VPN clients (such as GlobalProtect, Cisco AnyConnect, or NordVPN) frequently install their own virtual network adapters and apply strict firewall filters that override local Windows Firewall settings. If your local network testing fails, temporarily disconnect your VPN or check if your VPN profile blocks local subnet discovery (LAN access).

  3. Public vs. Private Network Profile Mismatch: If Windows categorizes your home Wi-Fi connection as a "Public" network profile, rules scoped strictly to -Profile Private will silently fail. Check your network profile status in PowerShell:

    Get-NetConnectionProfile
    

    If the NetworkCategory says Public and you trust your network, switch it to private:

    Set-NetConnectionProfile -InterfaceIndex <IndexNumber> -NetworkCategory Private
    

Cleaning Up Rules After Development

Leaving stale firewall rules open on your machine creates unnecessary attack surfaces. Once you finish testing or debugging your Node.js application, delete the port-based rule by running:

Remove-NetFirewallRule -DisplayName "Node.js Local Development"

If you prefer to automate this workflow, you can wrap your rule creation and teardown commands in a deployment script or a local package.json task runner, ensuring your firewall is only modified precisely when your local development stack is active.