📉 前言
很多人遇到 Claude Code / Claude Desktop 的 Preparing session... 卡死时,第一反应是“模型没响应”或“账号/授权有问题”。但在 macOS 的真实排障里,这类卡死更常见的本质是:本地执行环境(Cowork VM)没起来,而 VM 起不来的根因经常落在同一类问题上:依赖包下载/校验链路失败(超时、403、断流、校验不通过、代理不生效等)。
这篇文章不是“给你一堆可能原因”,而是把问题按工程闭环拆开:先用日志把问题定性到下载/VM,再把链路拆成可验证的检查点,最后给出在网络不稳定时最有效的兜底方案——手工补齐 rootfs/bundle 文件并让 Claude Desktop 不再反复重装。

时效说明(很重要):Claude Desktop / Claude Code 的版本、下载 URL、目录结构与 VM 机制会随时间演进。本文在 2026-06-11 之前的资料基础上,结合公开的官方文档与 GitHub Issue 中的现象进行校准。涉及具体 URL、版本号、文件名时,请优先以你本机日志和当前官方文档为准。
本文你将学到(深度 + 广度)
- 理论深度:
Preparing session在 Claude Desktop/Cowork 架构中意味着什么,hbbs/hbbr这类“网络问题直觉”为何在这里会误导。 - 系统架构:Cowork VM(本地 Linux VM)如何驱动 Claude Code 执行;下载 pipeline、校验与启动生命周期怎么串起来。
- 工程实践:用
main.log与cowork_vm_node.log在 1 分钟内定性问题;用一套“检查点清单”快速定位是代理、DNS、端口、403、断流还是校验失败。 - 兜底方案:网络差时如何手工补齐关键文件(尤其是体积最大的 rootfs),并避免 Claude 反复清理导致你永远卡在
Preparing session。 - 生产治理:如何把排障做成可复制的 Runbook:日志留存、版本锁定、缓存策略、升级回滚和安全注意事项。
🧩 一、问题定义:Preparing session 到底卡在哪个阶段?
先把“现象”翻译成“工程阶段”,排障才不会漂。
典型表现:
- Claude Desktop / Cowork 的 UI 长时间停在
Preparing session... - 偶发弹窗
Failed to start Claude's workspace - 日志里出现
net::ERR_CONNECTION_TIMED_OUT/ERR_CONNECTION_CLOSED/403 - 一直重试,任务始终无法进入可执行状态
这类问题通常意味着下面任意一环没闭环:
其中最容易失败、也最容易“看起来像模型卡死”的就是 B/C/D 三段:下载没完成、校验失败、rootfs 不完整,VM 根本起不来,于是 UI 永远停在 Preparing session。
🔍 二、核心结论:90% 的卡死都能用日志“定性到下载/VM”
很多教程会让你先删缓存、重装、重启机器。我的建议相反:先看两份日志,因为它们把问题直接指向“下载链路”还是“VM 生命周期”。
macOS 常见日志位置(以 Claude Desktop 为例,目录名可能随版本变化,以你本机实际为准):
~/Library/Logs/Claude-3p/main.log~/Library/Logs/Claude-3p/cowork_vm_node.log
2.1 main.log:定位“下载卡住/下载失败/校验失败”
你常会看到这类关键句:
Downloading bundle from https://downloads.claude.ai/...Download attempt ... failed Error: net::ERR_CONNECTION_TIMED_OUTERR_CONNECTION_CLOSEDchecksum ... failed/downloaded size ... mismatch
工程含义很清晰:不是模型“没响应”,而是 Claude Desktop 在准备本地执行依赖时失败。
2.2 cowork_vm_node.log:定位“rootfs 缺失/VM 启动失败/自动重装”
常见关键词:
rootfs.img missing/rootfs.img not found... downloading rootfs ...然后超时/403VM:start Startup failed ...Auto-reinstalling workspace after startup failure
如果你看到 rootfs 缺失或 VM 启动失败,那几乎可以直接断言:Preparing session 卡死不是“对话层”的问题,而是“执行环境层”的问题。
🏗️ 三、底层原理视角:为什么下载失败会让你误以为“模型卡住”?
Claude Desktop 的 Cowork/本地执行通常不是直接在你的 macOS 上跑 CLI,而是启动一个受控的本地 VM(Linux VM),在 VM 内运行执行组件(包括 Claude Code 相关二进制/依赖)。这带来两个影响:
- 下载与校验是 VM 启动的前置条件:rootfs/二进制不齐,VM 起不来,UI 就只能“准备中”。
- 网络路径可能分叉:你以为系统代理生效了,但 VM/下载组件可能走另一条路径(或受不同的限制/白名单影响),导致 host 能访问、VM 访问不了。
把它画成“控制面/数据面”的思维会更好理解:

你会发现:模型“是否能回答”并不是第一层前置条件。第一层是 VM 能不能启动并进入 ready 状态。
🧭 四、排障方法论:用“检查点”替代“玄学重装”
下面是一套我建议你固定下来的排障顺序。好处是:每一步都有明确的“通过/不通过”,不会陷入反复重启的循环。
4.1 检查点 0:版本与环境记录(为复现/回滚服务)
先记下三类信息:
- Claude Desktop 版本号(About 或安装包信息)
- Claude Code / Cowork 相关版本号(日志里通常会出现下载路径/版本号)
- 你的网络环境:直连/企业网关/本地代理(HTTP/HTTPS/SOCKS)、是否有安全软件拦截
这一步不是形式主义:很多 GitHub Issue 里同一类问题(例如 403、校验失败)往往和某段时间的下载域名策略或特定版本的下载 pipeline bug 相关。你没有版本信息,后续就只能“猜”。
4.2 检查点 1:downloads.claude.ai 是否可达(含 403)
公开 issue 中确实出现过 downloads.claude.ai 直接返回 403 导致无法补齐 rootfs.img.zst 的情况,进而 VM bundle 本地存在但 boot image 缺失,Cowork 无法启动。你需要先区分:你遇到的是“超时/断流”还是“明确 403”。 citeturn1search0
建议做两类验证:
- 浏览器或
curl -I直连验证(不走代理) - 显式指定代理的
curl -I --proxy ...验证(走代理)
提醒:不要把带鉴权参数的 URL、任何 token、企业网关地址写进公开日志/截图。
4.3 检查点 2:系统代理是否真的生效(以及生效范围)
在 macOS 上,很多代理软件 UI 显示“已开启”,但系统代理未生效,或只对部分协议生效。你至少要用系统工具确认一次(示例命令仅作为思路,具体以你环境为准):
scutil --proxynetworksetup -getwebproxy Wi-Fi(按你的网络服务名替换)
然后用 curl 做“同一 URL 的直连 vs 代理”对照测试,确认差异。
4.4 检查点 3:定性到“下载失败”还是“校验失败”
- 下载失败:超时、断开、速度极慢导致失败。
- 校验失败:下载看似完成,但校验/size mismatch,尤其在某些网络环境里可能发生“被截断但没有明确错误”的情况。
公开 issue 中确实有人报告“同一 URL,curl 正常,Claude Desktop 的下载 pipeline 报错/截断/校验失败”的现象,这类问题你越重试越慢,因为它会触发自动重装/清理,导致永远回到起点。 citeturn1search4
4.5 检查点 4:定性到“rootfs 没就绪”
如果 cowork_vm_node.log 明确提示 rootfs.img missing 或反复 Auto-reinstalling workspace,那就不要再浪费时间在“重启 UI”上了。你要解决的是:把 rootfs 和 bundle 文件补齐到 Claude 期望的位置。
🛠️ 五、解决方案分层:从最软到最硬(推荐按顺序)
下面给三层方案,你不需要一次全做完。
方案 A(优先):修复下载链路,让 Claude 自己把依赖补齐
适用:
- 你能稳定访问下载域名(直连或代理)
- 没有明显 403
- 没有持续校验失败
动作要点:
- 确保系统代理真实生效(必要时只开 HTTP/HTTPS,先别混 SOCKS)
- 临时关闭可能拦截大文件的安全软件/过滤器(企业环境按规定走审批)
- 避免频繁强杀 Claude Desktop(可能触发自动重装/清理,反而更难收敛)
方案 B(增强):锁定版本 + 避免反复清理 + 让下载一次成功
适用:
- 下载速度很慢但能下
- 多次重试会清掉临时文件导致回到起点
动作要点:
- 尽量在“网络最稳定的时间窗口”完成一次完整下载与校验
- 下载过程不要频繁重启/强杀
- 下载完成后再重启触发 VM 启动
方案 C(兜底):手工补齐 rootfs/bundle(最有效,但要更谨慎)
适用:
- rootfs 体积大(2GB+),反复断流
- 明确 403 导致无法自动下载
- Claude 下载 pipeline 反复校验失败,但
curl可正常下载
这套方案的核心不是“随便把文件放哪”,而是:
- 找到 Claude 期望的 bundle 目录(以你本机日志/目录为准)
- 把下载好的
rootfs.img.zst放进去 - 用
zstd解压生成rootfs.img - 避免自动重装标志导致它又把你文件清掉
- 重启 Claude 触发 VM 重新启动
目录结构在不同版本可能不同。你应该优先从
cowork_vm_node.log或下载日志里找到“bundle path”。如果原文里提到vm_bundles/claudevm.bundle,那只是一个典型形态,并非对所有版本永远成立。 citeturn1search3turn1search14
下载链接
https://downloads.claude.ai/claude-code-releases/{版本号}/darwin-arm64/rootfs.img.zst
复制到指定目录
cp ~/Downloads/rootfs.img.zst \
~/Library/Application\ Support/Claude-3p/vm_bundles/claudevm.bundle/rootfs.img.zst
手工补齐的“通用动作模板”(用你实际路径替换):
# 1) 停止 Claude Desktop(尽量正常退出,不要频繁强杀)
osascript -e 'tell application "Claude" to quit' || true
# 2) 定位 bundle 目录(示例:从日志里找到的目标目录)
BUNDLE="$HOME/Library/Application Support/Claude-3p/vm_bundles/claudevm.bundle"
mkdir -p "$BUNDLE"
# 3) 复制已下载的 rootfs 压缩包到目标目录(示例路径按你的实际下载位置改)
cp -f "$HOME/Downloads/rootfs.img.zst" "$BUNDLE/rootfs.img.zst"
# 4) 解压生成 rootfs.img
zstd -d -f "$BUNDLE/rootfs.img.zst" -o "$BUNDLE/rootfs.img"
# 5) 清理可能触发自动重装/重复尝试的标记(按实际存在的文件名为准)
rm -f "$BUNDLE/.auto_reinstall_attempted" 2>/dev/null || true
# 6) 重新打开 Claude Desktop
open -na /Applications/Claude.app
为什么这能一锤定音?因为它把“最大、最脆弱、最容易失败的下载步骤”从 Claude 内部 pipeline 拆出来,用更可控的下载方式完成,再把结果放回正确位置,让 VM 启动不再被阻塞。
✅ 六、验证闭环:怎么确认真的修好了?
只看 UI 变了不够,建议按三层验证:
6.1 文件层
确认 rootfs.img 真实存在且体积合理(rootfs 解压后通常是 GB 级,具体取决于实现与版本): citeturn1search3turn1search14
ls -lah "$BUNDLE/rootfs.img" "$BUNDLE/rootfs.img.zst"
6.2 日志层(最可靠)
回到 cowork_vm_node.log,你希望看到类似:
... checksum validatedAll files ready ...VM:start Startup complete
若你仍看到 rootfs.img missing、反复 Auto-reinstalling、或 403/超时,那说明你补齐的位置不对、文件不完整、或启动时又被清理了。
6.3 业务层
回到 Claude Code / Cowork:
- 新开一个 session
- 执行一个最简单的动作(例如列目录/打印工作目录)
- 确认不再卡
Preparing session
🧯 七、常见坑与生产建议(把“偶发问题”降为“可控事件”)
7.1 频繁强杀导致“永远回到起点”
某些情况下,强杀可能会让下载 pipeline/自动修复逻辑更激进:它清理临时文件、触发自动重装,然后你又要从 0 开始下 rootfs。
建议:
- 尽量正常退出 Claude Desktop
- 真要强杀,也要先确保你已补齐关键文件且不会被清理
7.2 代理 UI 显示开启,但系统代理未生效
以系统工具输出为准(scutil --proxy 等)。仅靠代理软件 UI 容易误判。
7.3 host 能下载,VM/下载组件不能
这是最“反直觉”的点:你用浏览器能打开下载页,但 Claude 的下载组件仍失败。原因可能包括:
- VM/下载组件的网络路径与系统不同(白名单、证书、代理范围不同)
- 下载 pipeline 在特定网络环境下出现截断/校验失败(curl 正常,应用内不正常) citeturn1search4
解决思路是:回到日志定性,再决定是修网络路径还是走手工补齐。
7.4 磁盘空间与 bundle 体积增长
公开讨论里有人提到 vm_bundles 体积可能增长到 10GB+,这会带来性能问题与磁盘压力。你需要把它纳入“容量治理”,而不是等磁盘爆了才处理。 citeturn1search3
建议:
- 定期监控
~/Library/Application Support/...的空间占用 - 升级/回滚前做备份与清理策略
- 不要无脑删除 bundle(可能触发重新下载与更大成本)
🔐 八、安全与合规边界(别把排障变成泄密)
排障过程中最容易泄露的不是“命令”,而是:
- 带鉴权参数的下载 URL
- 企业代理/网关地址
- 账号相关的 token、cookie
- 真实工作区路径、项目名
建议:
- 截图/粘贴日志前先打码敏感信息
- 不要把任何 token 写进 shell 历史或脚本
- 在企业环境中按安全规范处理代理与证书
✅ 总结与展望
Claude Code/Claude Desktop 卡在 Preparing session 的关键不是“再重启一次”,而是把问题从 UI 现象还原为执行环境启动链路:
- 用
main.log定性下载/校验问题; - 用
cowork_vm_node.log定性 rootfs/VM 生命周期; - 按检查点逐个排除代理、403、断流、校验失败;
- 网络差或 pipeline 不稳定时,直接走“手工补齐 rootfs/bundle”的兜底方案;
- 用文件层 + 日志层 + 业务层形成验证闭环。
关键要点回顾
Preparing session很多时候是 VM 没起来,而不是模型没响应。downloads.claude.ai的 403/超时/断流/校验失败都可能直接导致 rootfs 缺失,从而卡死。 citeturn1search0turn1search4curl能下不代表 Claude 下载 pipeline 一定能下;必要时把最大文件(rootfs)拆出来手工补齐。- 把排障写成 Runbook(记录版本、链路、目录、验证点)能显著降低后续的时间成本。
下一步学习
- 从官方 Claude Code Desktop 文档理解 Cowork/桌面架构与限制(网络白名单、桌面能力等)。

如果这篇文章对你有帮助,欢迎关注、点赞和收藏。
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/dreamcatcher1314/article/details/161904406




