PAYATHON 2026

VS Code 1.106.3 更新后 Jupyter kernel 等待端口超时

排障赵师傅

结论

这条错误说明 VS Code 尝试启动本地 ipykernel 后,未能在规定时间内检测到 kernel 通信端口进入预期状态。

单凭这条错误,无法判断具体属于哪种情况:

  • kernel 进程未能启动;
  • 进程启动后立即崩溃;
  • kernel 已启动,但没有绑定 connection file 中的端口;
  • 端口已经绑定,但 VS Code/Jupyter extension 未能正确检测;
  • 安全软件、临时目录权限、环境变量或扩展宿主异常拖慢了启动过程。

目前也没有足够的信息证明这是 VS Code 1.106.3 与 Python 3.12 的已知兼容性问题。故障是在 VS Code 更新后出现的,确实需要排查 regression,但还要通过干净环境、旧版扩展或旧版 VS Code 进行对照测试才能确认。

为什么外部 Jupyter 正常仍不能排除 kernel 问题

下面的命令启动的是 Jupyter Notebook Server:

python -m jupyter notebook --no-browser

VS Code 启动本地 notebook kernel 时,执行过程更接近:

python -m ipykernel_launcher -f <connection-file>

这两条路径使用的组件和启动参数并不完全相同。Notebook Server 能够监听 HTTP 端口,只能说明 Python 和 Jupyter Server 基本可以运行。它无法证明 ipykernel 能根据 connection file 建立 shell、iopub、stdin、control 和 heartbeat 等通信端口。

日志中的这一段:

c:\Program Files\Python312\python.exe.-m#ipykernel_launcher

表明 VS Code 选择的是 C:\Program Files\Python312\python.exe。路径中包含空格是合法的,不过仍要查看完整日志,确认实际启动命令是否正确处理了引号。

先验证同一个解释器

不要直接调用可能指向其他 Python 的 pip 或 jupyter。请在 PowerShell 中明确指定解释器:

& 'C:\Program Files\Python312\python.exe' -c "import sys; print(sys.executable); print(sys.version)"
& 'C:\Program Files\Python312\python.exe' -m pip --version
& 'C:\Program Files\Python312\python.exe' -m pip check
& 'C:\Program Files\Python312\python.exe' -m jupyter --version
& 'C:\Program Files\Python312\python.exe' -m pip show ipykernel jupyter_client pyzmq tornado traitlets

检查以下几项:

  • sys.executable 是否与 VS Code 日志中的路径一致;
  • pip check 是否报告依赖冲突;
  • ipykernel、jupyter_client 和 pyzmq 是否安装在这个解释器中;
  • 是否混用了用户级、系统级或其他虚拟环境中的包。

用下面的命令查看 kernelspec:

& 'C:\Program Files\Python312\python.exe' -m jupyter kernelspec list

如果列表中有多个同名或已经失效的 Python 3.12 kernelspec,可以创建一个名称明确的新条目:

& 'C:\Program Files\Python312\python.exe' -m ipykernel install --user --name py312-vscode-test --display-name "Python 3.12 VS Code Test"

然后在 notebook 右上角重新选择 Python 3.12 VS Code Test。

直接测试 ipykernel 能否绑定端口

先关闭 VS Code 中正在启动的 kernel,再在 PowerShell 中执行:

$connectionFile = Join-Path $env:TEMP 'kernel-vscode-test.json'
Remove-Item $connectionFile -ErrorAction SilentlyContinue

& 'C:\Program Files\Python312\python.exe' -m ipykernel_launcher -f $connectionFile

如果命令持续运行,既没有立即返回,也没有输出 traceback,通常说明 kernel 进程仍然存活。此时另开一个 PowerShell 窗口,检查 connection file:

Get-Content (Join-Path $env:TEMP 'kernel-vscode-test.json')

文件中应包含若干非零端口,结构类似:

{
  "shell_port": 0,
  "iopub_port": 0,
  "stdin_port": 0,
  "control_port": 0,
  "hb_port": 0
}

成功启动后,这些值通常会变成具体的端口号。如果进程立即退出、文件没有生成,或终端中出现 PermissionError、模块导入错误、DLL 加载失败等信息,应先修复 Python 环境。

测试结束后,在运行 kernel 的窗口中按 Ctrl+C 停止进程。

用干净虚拟环境做对照测试

干净的虚拟环境有助于判断故障来自 VS Code regression,还是现有 Python 环境。建议将测试环境放在用户可写目录中,避开 Program Files:

py -3.12 -m venv "$env:USERPROFILE\venvs\vscode-jupyter-test"
& "$env:USERPROFILE\venvs\vscode-jupyter-test\Scripts\python.exe" -m pip install --upgrade pip
& "$env:USERPROFILE\venvs\vscode-jupyter-test\Scripts\python.exe" -m pip install ipykernel

在 VS Code 中将这个环境选为 notebook kernel,然后运行:

import sys
print(sys.executable)
print("kernel started")

根据测试结果继续排查:

  • 新环境正常,说明原 Python 安装、用户级包或 kernelspec 更可疑;
  • 新环境也失败,应重点检查 VS Code、Jupyter extension、扩展宿主或系统级拦截;
  • 只有特定工作区失败,应检查该工作区的 .vscode/settings.json、环境文件和工作区信任状态。

排查 extension 冲突

code --disable-extensions 会同时禁用 Jupyter extension,所以不能用它单独证明其他 extension 没有冲突。如果启动命令复用了已有窗口,测试结果还可能受到原窗口状态的影响。

可以按以下步骤建立干净的测试环境:

  1. 完全退出所有 VS Code 窗口。
  2. 创建一个空白 VS Code Profile。
  3. 只启用 Microsoft Python 和 Jupyter 所必需的扩展。
  4. 打开一个新目录和最小 notebook。
  5. 使用前面创建的干净虚拟环境。

也可以运行 VS Code 的 Help: Start Extension Bisect,但要确保 Jupyter 和 Python 扩展始终保持启用。

应收集哪些日志

复现问题后,至少保留以下信息。

Jupyter Output

打开 View → Output,选择 Jupyter,复制从选择 kernel 到出现超时报错为止的完整内容,不要只截取最后一行。

检查其中是否包含:

  • 实际执行的 Python 路径和参数;
  • connection file 路径;
  • kernel PID;
  • 进程退出码;
  • stderr 或 traceback;
  • 端口分配和等待过程;
  • ENOENT、EACCES、EPERM、ModuleNotFoundError、DLL load failed 等错误。

Python 和扩展宿主日志

同时查看 Output 面板中的 Python、Log (Extension Host) 等相关通道。如果当前版本支持按日志通道调整级别,可以通过 Developer: Set Log Level 临时切换到 Trace,然后再次复现问题。

Developer Tools console 可以作为补充。kernel 的启动细节通常在 Jupyter Output 中更完整。

环境快照

& 'C:\Program Files\Python312\python.exe' -m jupyter --version
& 'C:\Program Files\Python312\python.exe' -m pip list
& 'C:\Program Files\Python312\python.exe' -m pip check
& 'C:\Program Files\Python312\python.exe' -m jupyter kernelspec list
Get-ChildItem Env: | Where-Object Name -Match 'PYTHON|JUPYTER|IPYTHON|VIRTUAL_ENV'

公开提交日志前,删除其中的用户名、访问令牌、远程服务器 URL 和其他敏感路径信息。

Windows 上还要检查的项目

先确认临时目录可以正常读写:

$testFile = Join-Path $env:TEMP 'vscode-jupyter-write-test.txt'
'write test' | Set-Content $testFile
Get-Content $testFile
Remove-Item $testFile

如果测试失败,kernel connection file 也可能无法正常创建。

还需要检查:

  • Windows Defender 的 Controlled Folder Access;
  • 企业 EDR 或 antivirus 是否拦截 python.exe 子进程、ZeroMQ 或本地回环连接;
  • VPN、代理或网络过滤软件是否干预 127.0.0.1;
  • 是否设置了 PYTHONHOME、PYTHONPATH、JUPYTER_PATH 等全局环境变量;
  • VS Code 是否使用了不同的用户或权限级别运行;
  • %TEMP% 中的文件是否被清理工具实时删除。

添加防火墙放行规则不一定能排除安全软件的影响。有些产品允许程序联网,但会阻止进程创建、DLL 加载或本地进程间通信。

回滚前可以尝试的修复

按下面的顺序测试,每次只改变一个变量:

  1. 使用全新的虚拟环境作为 kernel。
  2. 在空白 Profile 中只启用 Python 和 Jupyter 扩展。
  3. 删除并重新创建有问题的 kernelspec,避免继续使用旧条目。
  4. 如果有更新版本,分别测试较新的 VS Code 补丁版和 Jupyter extension。
  5. 通过扩展页面中的 Install Another Version 暂时测试上一版 Jupyter extension。
  6. 最后使用旧版 VS Code 做对照。

还可以先在终端中启动 Jupyter Server,再让 VS Code 连接到现有服务器。这样可以绕过部分本地 kernel 启动管理逻辑。由于命令名称和连接入口可能随 Jupyter extension 版本变化,请在命令面板中查找 Jupyter Server 的选择或连接命令。连接 URL 通常包含 token,不要将其公开粘贴。

如果旧版 Jupyter extension 在同一 VS Code 1.106.3 和同一虚拟环境下可以正常运行,而新版失败,问题更可能出在 extension regression。要判断是否为 VS Code regression,则需要确认同一扩展在旧版 VS Code 中正常、在 1.106.3 中失败。完成这种单变量对照后,版本结论才比较可靠。

备注:内容仅供参考。