How to Diagnose and Remove Port Exclusions in Windows After SQL Server Port Blocking Issue


3 views

After the Windows 10 2004 update, many developers (myself included) started encountering connection issues with SQL Server running on default port 1433. The root cause appears to be Windows' dynamic port exclusion mechanism which now reserves ranges that can include common database ports.

Windows maintains a list of excluded TCP/UDP port ranges that can be viewed using PowerShell:

# View current TCP port exclusions
netsh int ipv4 show excludedportrange protocol=tcp

# For UDP ports
netsh int ipv4 show excludedportrange protocol=udp

Modern Windows versions use port exclusion for:

  • Hyper-V dynamic port allocation (especially after enabling WSL2)
  • Docker container networking
  • Windows NAT driver (winnat) reservations
  • Third-party VPN software conflicts

The standard deletion command often fails because:

# This frequently returns "Element not found"
netsh int ipv4 delete excludedportrange protocol=tcp startport=1414 numberofports=1000

Try these proven solutions:

Method 1: Complete Port Exclusion Reset

# Stop services that manage port allocations
net stop winnat
net stop hns

# Clear all dynamic exclusions (requires admin)
netsh int ipv4 reset

# Restart services
net start winnat
net start hns

Method 2: Manual Registry Modification

For persistent exclusions marked with asterisk (*) in the list:

# Navigate to:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\hns\State

# Delete the "ExcludedPorts" value
# Requires system reboot to take effect

To permanently reserve your SQL Server port:

# Add a persistent exclusion (admin rights required)
netsh int ipv4 add excludedportrange protocol=tcp startport=1433 numberofports=1

# Verify it shows with asterisk (*) marker
netsh int ipv4 show excludedportrange protocol=tcp

If you can't modify the exclusion list:

  • Configure SQL Server to use different ports (e.g., 14333)
  • Set up port forwarding using PowerShell:
    netsh interface portproxy add v4tov4 listenport=1433 connectport=14333 connectaddress=127.0.0.1
    
  • Disable Hyper-V if not needed (affects WSL2 functionality)

Check for port conflicts using these commands:

# Find which process uses a port
netstat -ano | findstr "1433"

# Cross-check with tasklist
tasklist | findstr "PID_from_netstat"

# Monitor real-time port activity
Get-NetTCPConnection -State Listen | Where-Object LocalPort -eq 1433

After upgrading to Windows 10 2004, many developers report suddenly being unable to bind to common database ports like 1433. The culprit appears in the command:

netsh int ipv4 show excludedportrange protocol=tcp

Which reveals ranges like:

Start Port    End Port
----------    --------
     50000       50059     *

These exclusions typically come from three sources:

  • Hyper-V dynamic ports: Automatically reserved during Windows updates
  • Third-party services: Antivirus or VPN software may claim ports
  • System components: Features like Windows Container Service

The standard deletion command often fails:

netsh int ipv4 delete excludedportrange protocol=tcp startport=50000 numberofports=60

Try this nuclear option (requires admin):

# Disable Windows NAT driver
Disable-NetNatTransitionConfiguration -Confirm:$false

# Restart TCP/IP stack
netsh int ipv4 reset
netsh int ipv6 reset

# Reboot afterward

For SQL Server specifically, consider these alternatives:

-- Change SQL Server default port
USE master;
GO
EXEC xp_instance_regwrite 
    'HKEY_LOCAL_MACHINE',
    'Software\Microsoft\MSSQLServer\MSSQLServer\SuperSocketNetLib\Tcp',
    'TcpPort',
    REG_SZ,
    '51433';
GO

Or create a persistent reservation:

# Requires Windows Pro/Enterprise
netsh int ipv4 add excludedportrange protocol=tcp startport=1433 numberofports=1 store=persistent

This PowerShell checks all excluded ports against running services:

$excluded = netsh int ipv4 show excludedportrange protocol=tcp | 
    Where-Object { $_ -match '\d+\s+\d+' }

$excluded | ForEach-Object {
    $range = $_ -split '\s+' | Where-Object { $_ }
    $start = [int]$range[0]
    $end = [int]$range[1]
    
    Get-NetTCPConnection -State Listen | Where-Object {
        $_.LocalPort -ge $start -and $_.LocalPort -le $end
    } | Select-Object LocalPort, OwningProcess, @{
        Name="Process";Expression={(Get-Process -Id $_.OwningProcess).Name}
    }
}