启用WSL2可能会导致IDEA启动失败?

偶尔在启动 IDEA 或 PyCharm 时会失败并报错:java.net.BindException: Address already in use: bind


现象

完整错误信息和报错截图如下:

完整错误信息 >folded
Internal error. Please refer to https://jb.gg/ide/critical-startup-errors

com.intellij.ide.plugins.StartupAbortedException: Cannot start app
at com.intellij.idea.StartupUtil.lambda$start$15(StartupUtil.java:263)
at java.base/java.util.concurrent.CompletableFuture.uniExceptionally(CompletableFuture.java:986)
at java.base/java.util.concurrent.CompletableFuture$UniExceptionally.tryFire(CompletableFuture.java:970)
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506)
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1705)
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1692)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
Caused by: java.net.BindException: Address already in use: bind
at java.base/sun.nio.ch.Net.bind0(Native Method)
at java.base/sun.nio.ch.Net.bind(Net.java:459)
at java.base/sun.nio.ch.Net.bind(Net.java:448)
at java.base/sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:227)
at io.netty.channel.socket.nio.NioServerSocketChannel.doBind(NioServerSocketChannel.java:134)
at io.netty.channel.AbstractChannel$AbstractUnsafe.bind(AbstractChannel.java:562)
at io.netty.channel.DefaultChannelPipeline$HeadContext.bind(DefaultChannelPipeline.java:1334)
at io.netty.channel.AbstractChannelHandlerContext.invokeBind(AbstractChannelHandlerContext.java:506)
at io.netty.channel.AbstractChannelHandlerContext.bind(AbstractChannelHandlerContext.java:491)
at io.netty.channel.DefaultChannelPipeline.bind(DefaultChannelPipeline.java:973)
at io.netty.channel.AbstractChannel.bind(AbstractChannel.java:260)
at io.netty.bootstrap.AbstractBootstrap$2.run(AbstractBootstrap.java:356)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:503)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:829)

-----
Your JRE: 11.0.15+10-b2043.56 amd64 (JetBrains s.r.o.)
C:\Program Files\JetBrains\IntelliJ IDEA 2022.1.4\jbr

IDEA启动失败

原因

大多数人遇到的这个问题都是因为启用了 WSL 2,原因如下:

  1. IDEA 在启动时会从 69426991 范围内选择一个可用的端口用作内部的 IPC 通信;
  2. Windows 为了与 WSL 2 端口互通,需要预留大段端口做转发,因此可能会占用到 IDEA 选择范围内的所有端口;
  • 系统会优先从动态端口范围内选择为 WSL 2 保留的端口,Windows 早期版本的动态端口范围为10255000,后来为了遵守 IANA 规范改为了 4915265535
  • 但某些 Windows 更新或驱动为了兼容性考虑可能会修改默认的动态端口范围。
  1. IDEA 启动时发现没有端口可用,报错 Address already in use: bind

解决

要解决 IDEA 由于端口绑定失败而无法启动的问题,核心思路就是要避免 69426991 端口被系统分配给 WSL 2 等组件。有以下两种方式可以实现该效果:

  • 将 IDEA 需要的端口设置为排除端口,禁止系统组件占用。
  • 修改动态端口范围,避开 IDEA 需要的端口,减少这些端口被系统组件占用的可能。

简单来说,“排除端口”是用来告诉系统不要让系统组件占用这部分端口,“动态端口”用来告诉系统优先考虑给系统组件分配这部分端口

添加排除端口

排除端口(Excluded Port)是 Windows 内核预留的一部分端口,避免被其他进程占用导致NAT/Hyper-V/Windows Defender 等系统组件无法正常工作。除了系统预留的端口外,用户也可以手动指定排除端口,用户排除端口不会被系统分配给系统组件,但可以被 IDEA 等程序使用。

查看排除端口的范围:

PS> netsh interface ipv4 show excludedportrange protocol=tcp
协议 tcp 端口排除范围
开始端口 结束端口
---------- --------
1593 1692
1993 2092
2193 2292
5357 5357
6721 6820
6899 6998
6999 7098
7891 7990
8779 8878
9248 9347
50000 50059 *
* - 管理的端口排除。

可以看到 68996998 这一段端口已经被保留给了某个组件,因此 IDEA 此时无法绑定到 69426991 范围内的任何端口。现在只能重启系统,释放被系统保留的端口,再添加用户排除端口

# 配置ipv4网络,添加端口排除范围,协议为tcp,起始端口为6942,数量为50
PS> netsh interface ipv4 add excludedportrange tcp startport=6942 numberofports=50
确定。

确认修改后的排除端口范围:

PS> netsh interface ipv4 show excludedportrange tcp
协议 tcp 端口排除范围
开始端口 结束端口
---------- --------
5357 5357
6942 6991 *
50000 50059 *
...
* - 管理的端口排除。

如果不再想要为 IDEA 保留端口,可以删除排除端口

PS> netsh interface ipv4 delete excludedportrange tcp startport=6942 numberofports=50
确定。

修改动态端口范围

动态端口(Dynamic Port)是操作系统在进程需要网络通信时临时分配的端口,系统在为 WSL 2 等组件保留端口时会更倾向于选择动态端口范围内的端口。从动态端口范围中将 IDEA 需要的端口移除,即可很大程度避免被 WSL 2占用。

Windows 早期版本的动态端口范围为 10255000,从 Windows Vista/Windows Server 2008 开始改为了符合互联网号码分配局(IANA)建议的 4915265535

运行 Powershell,查看动态端口范围:

PS> netsh int ipv4 show dynamicport tcp
协议 tcp 动态端口范围
---------------------------------
启动端口 : 1024
端口数 : 13977

可以看到系统当前的 tcp 动态端口范围被修改为 102415000 这 13977 个端口,并非默认的 4915265535,可能也是这个原因,导致了低位的端口号也被拿去分配给了系统组件。

修改动态端口范围:

PS> netsh int ipv4 set dynamicport tcp start=49152 num=16383
确定。

确认修改后的排除端口范围:

PS> netsh int ipv4 show dynamicport tcp
协议 tcp 动态端口范围
---------------------------------
启动端口 : 49152
端口数 : 16383

复现

编写 Python 脚本,模拟端口占用情况:

port_terrorist.py
import socket

sockets = []
start_port = 6942 # 起始端口
num_ports_to_occupy = 49 # 占用多少个端口

for port in range(start_port, start_port + num_ports_to_occupy):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 设置为ipv4和使用tcp协议
s.bind(('localhost', port)) # 绑定地址和端口
s.listen(1)
sockets.append(s)

print(f"Occupied ports {start_port} to {start_port + num_ports_to_occupy - 1}")
input("Press Enter to release ports and exit...")
for s in sockets:
s.close()

运行脚本占用 69426991 端口,此时再运行 IDEA 就会报错;如果修改脚本减少一个占用的端口,此时 IDEA 能够启动。

打开任务管理器,进入性能栏,点击右上角三个点,选择资源监视器,在侦听端口一栏内可以看到 idea64.exe 进程使用的端口确实是 6991

idea64.exe侦听端口

也可以在 Powershell 中执行下面的命令查看 69426991 端口占用情况:

PS> Get-NetTCPConnection |
Where-Object { $_.LocalPort -ge 6942 -and $_.LocalPort -le 6991 } |
Select-Object LocalAddress, LocalPort, State, @{Name="ProcessName";Expression={(Get-Process -Id $_.OwningProcess).Name}} |
Sort-Object LocalPort |
Format-Table -AutoSize
LocalAddress LocalPort State ProcessName
------------ --------- ----- -----------
127.0.0.1 6942 Listen python
...
127.0.0.1 6990 Listen python
127.0.0.1 6991 Listen idea64

端口查询命令

根据端口范围查询使用的进程:

PS> Get-NetTCPConnection |
Where-Object { $_.LocalPort -ge 6942 -and $_.LocalPort -le 6991 } |
Select-Object LocalAddress, LocalPort, State, @{Name="ProcessName";Expression={(Get-Process -Id $_.OwningProcess).Name}} |
Sort-Object LocalPort |
Format-Table -AutoSize

根据进程名称反查占用端口:

PS> Get-Process -Name idea64 | ForEach-Object { Get-NetTCPConnection -OwningProcess $_.Id }

参考资料

Revise IDE directory locking mechanism (don’t fail startup if all ports in range are taken, limited network due to firewall/VPN)
Windows Server - TCP/IP 的默认动态端口范围已更改
Windows Server - netsh interface

启用WSL2可能会导致IDEA启动失败?

https://thinklong.me/jetbrains-start-failed/

作者

ThinkLong

发布于

2025-09-24

更新于

2025-12-11

许可协议

评论

+