发布日期:2026-11-07 | 环境:Windows / DSH 桌面端(Electron,本地 Host 监听 127.0.0.1 随机端口,本机未记录应用版本号)| 验证情况:cookie 清理与插件配置还原已在本机执行并读回校验;应用重启、社区修复插件均未实测 | 结论先行:这不是认证坏了,是 71 条 dsh-auth-* cookie 把 Cookie 请求头撑过 Node 默认 16,384 字节上限,本地 Host 返回 HTTP 431,而上层把 431 统一报成了「Web authentication failed」。


1. 事故现场:一切看起来都正常,就是进不去

2026-11-07 早上开机,DSH 桌面端没起来。账号没过期,密钥没改,网络是通的,任务、会话、插件全都好好躺在磁盘上——唯独主窗口进不去。弹窗只有一句冷冰冰的 desktop welcome: Web authentication failed,还附了一句很吓人的提示:"If application files are missing or damaged, close the application and reinstall it."

DSH启动失败弹窗截图.jpg

弹窗全文(截图里逐字可核对):

  • 标题:DeepSeek Harness is unavailable
  • 正文:The application could not start or stopped unexpectedly.
  • 子项错误:desktop welcome: Web authentication failed
  • Diagnostic report: 指向 %APPDATA%\@d...\crash-2026-11-07T01-26-45-201Z-host.log
  • 附加说明:If application files are missing or damaged, close the application and reinstall it. Your tasks are stored separately.

三个按钮:Exit / Restart / Disable third-party plugins, back up profile patch, and restart。

那天一共崩了 9 次,9 份崩溃日志一字不差:

phase: startup
Error: desktop welcome: Web authentication failed
at connectDesktopWelcome (app.asar/lib/main.js:8886)

最反差的地方在于:错误信息把人往「认证」「密钥」「文件损坏」三个方向带,而真凶在完全不相干的地方——一个 SQLite 文件里攒了两年的……不,攒了两个月的 cookie。

2. 为什么常规手段救不了

我把能想到的都试了一遍,全部失灵。事后看,每一次失灵都是有原因的:

常规做法我做了什么为什么失灵
重新安装应用按弹窗那句 "application files are missing or damaged" 怀疑文件损坏cookie 库在 userData 目录(%APPDATA%\@deepseek-ai\dsh-desktop\Network\Cookies),卸载重装根本不碰它,71 条还在
换账号 / 换 API Key把错误里的 "authentication" 当成凭据问题401 和 431 共用同一句 Web authentication failed,上层只判断 response.ok;凭据类问题一般发生在模型请求阶段,界面还能打开
反复点 Restart弹窗上最显眼的按钮每次启动监听随机端口 → 新增一条 cookie,点一次多一条,越点越接近上限,9 次崩溃日志完全一致就是这么来的
「禁用第三方插件,备份配置并重启」以为是"干净启动"能绕开它只把 desktop profile 的 cordis.patch.yml 清空成 [],对 cookie 毫无影响;反而丢了 3 个第三方插件条目,后面要额外花十几分钟还原
查 Windows 事件查看器 / WER怀疑系统级崩溃、显卡驱动当天没有与该应用相关的系统级崩溃;BlueScreen / LiveKernelEvent 是 10/25、11/5 旧 dump 的重复上报;唯一 APPCRASH 是 NVDisplay.Container.exe(NVIDIA 显示容器),无关

一句话:故障在用户数据目录,而所有常规手段都在动程序目录、账号和网络。方向错了,越努力越糟。

3. 根因:三个角色,一条链路

拆开看是三个角色各自"合理",凑一起就成了必然事故:

角色它做了什么单独看有没有问题
本地 Host每次启动监听 127.0.0.1 的随机端口;认证 cookie 名 = dsh-auth- + base64url(sha256(Host authority)),30 天 Max-Age,没有删除旧名的路径合理,端口随机本来是为了避免占用
Chromium cookie 库按「域名 + 路径 + 名字」存,名字不同就是新的一行;发请求时按域名合并,不管端口合理,这是浏览器标准行为
上层错误处理connectDesktopWelcome 只判断 response.ok,把 401 和 431 一起包成 Web authentication failed省事,但把最关键的状态码吞了

链路:

随机端口 → cookie 名带端口哈希 → 每次启动 +1 条、30 天有效、从不清理
→ Chromium 按域名把 71 条全塞进同一个 Cookie 头
→ 超过 Node 默认 16,384 字节 → 本地 Host 直接回 431
→ 上层只判 response.ok → 报「Web authentication failed」→ 开机启动失败

本机证据:

证据项数值
dsh-auth-* cookie 数量71 条,全部在 127.0.0.1 下
仅 Cookie 头大小16,023 字节
Node HTTP 服务器默认请求头上限16,384 字节
叠加 UA / Accept 等固有请求头超过上限 → HTTP 431 Request Header Fields Too Large
当天崩溃次数9 次,日志完全一致

社区侧还有一份更细的边界计算:每条约 226 字节(52 字节名字 + 1 字节等号 + 173 字节值),71 条加 70 个 ; 分隔符约 16,186 字节,60 条约 13,824 字节正常,65 条开始部分环境失败,71 条必然 431——见 #10828。这个算法来自社区教程,我本机只测到了 16,023 字节这个总数,没有逐条复算。

关键点:旧 cookie 对认证本身没有用。authenticate() 只找当前端口对应的那一条,剩下 70 条纯属头部负担。所以"清掉会不会掉登录态"的答案是不会——会话、插件、凭据分别在 sessions、profile、.credentials.yaml 里,跟这个库互不相干。

相关上游讨论(本次逐条核验,链接见第 10 节):#10831 报启动失败与 cookie 累积,#11366 报 rc.2 / rc.3 稳定复现,#11148 是根因分析,#11408 建议把 HTTP 状态码带进错误文案。

4. 三个关键决策,每个都对应一次真实踩坑

决策一:只删 dsh-auth-* 行,不移走整个 Cookies 库

社区教程把"整个 Network/Cookies 改名让应用重建"列为推荐做法,最快、最稳。但我在排查中刚误点过「禁用第三方插件并备份配置」,把 cordis.patch.yml 清空成 [],已经丢了一次配置。刚踩过"扩大破坏面"的坑,就不想再动全量 cookie 库,何况内嵌浏览器里还有其他站点 cookie。于是选了定向删除:先备份,再 DELETE ... WHERE name LIKE 'dsh-auth-%',只碰自己家的行。

代价是必须自己写 SQL、自己跑完整性检查,比"改个名"多两步。

决策二:不装社区修复插件

GitHub 上已经有人做了自动清理插件(第 8 节列了三个)。我没装,两个原因:一是本机规范里"任何加包/安装都要先确认",没人点头就不能动依赖图;二是"重装、换配置"这类动作当天已经被证明无效还加重问题,再往启动流程里挂一个插件,等于改变故障面、把真因盖住。

代价很明确:这个 bug 会复发,我只是把计数归零,没有根治。

决策三:还原插件配置时,保留当前默认模型

清空 patch 之后,应用首次启动按向导重写了一份 55 行的精简配置,默认模型变成了本地 provider。而原版备份里默认模型是需要 API Key 的远程 provider。如果直接把 298 行备份整份盖回去,下次启动很可能因为缺 Key 而不可用。所以最终做法是:备份内容全量还原,只把 agent-default-model 两行保留为当前值。

读回校验时,还原后的文件与原版备份只差这两行。

附:还有一个不算决策的硬前提

必须完全退出应用再动 cookie 库。SQLite 的 WAL 和内存缓存可能在退出时把旧行写回,出现"删了但没生效"(社区教程明确点过这一条)。这次是在应用完全没运行时才做的,这也是当时少数几个走对的步骤。

5. 时间线与数字是怎么来的

时间(2026-11-07,+08)阶段动作 / 证据
09:26发现首个崩溃日志 crash-2026-11-07T01-26-45-201Z-host.log;当天 9 次崩溃日志完全一致
09:27弯路点「禁用第三方插件并备份配置」,生成 13,022 字节原版 patch 备份;patch 被清空
09:41弯路又生成两份 217 字节、内容为 [] 的备份,说明还在反复试该按钮 / Restart
09:53处理备份 Network\Cookies(53,248 字节),定向删除 71 条 dsh-auth-*
09:56恢复应用启动成功,三个 profile 的 patch 被重写;默认模型被首次向导改成本地 provider
10:06处理把当时的精简版 patch 备份进 $DSH_HOME\trash\20261107-100643-...\
10:07处理用原版备份还原 cordis.patch.yml,只保留 2 行默认模型不动
10:09留档写出 234 行排查记录文档
12:42本次联网核验 GitHub 讨论与社区仓库链接,写这篇博客

按文件时间戳推算:09:26 → 09:56 约 30 分钟(其中约 15 分钟花在禁用插件与反复重启的弯路上),09:56 → 10:07 约 11 分钟做插件配置还原。

数字逐个交代来源,不含估算以外的成分:

  • 71 条 / 16,023 字节:本机 cookie 库读出来的实测值。
  • 16,384 字节:Node HTTP 解析器默认上限,社区讨论 #10828 的标题也在讲这个边界。
  • 16,186 字节 / 60 条 13,824 B / 65 条开始失败:来自社区教程的推算表,本机未复算。
  • 53,248 字节:本次备份文件实际大小。
  • 13,022 字节 / 298 行 → 1,743 字节 / 55 行 → 13,021 字节 / 298 行:patch 文件的三次状态,字节数由文件系统读出。
  • 3 个 insert 条目:还原后数 - insert: 得到的。
  • 约 70 次启动复发:由 71 条触发、每次启动 +1 条、30 天有效期推出来的,不是实测周期。

6. 抄作业步骤

先决条件(缺一不生效)

  1. 应用完全退出,包括托盘图标和后台残留进程;任务管理器里不能有相关进程。
  2. 动手前先备份 Network/Cookies。
  3. 需要一个能打开 SQLite 的工具(本次用 Node 内置 SQLite)。
  4. cookie 库路径:Windows 在 %APPDATA%\@deepseek-ai\dsh-desktop\Network\Cookies;macOS 在 ~/Library/Application Support/@deepseek-ai/dsh-desktop/Network/Cookies。

第 1 步:备份

$dir = Join-Path $env:APPDATA '@deepseek-ai\dsh-desktop\Network'
Copy-Item -LiteralPath (Join-Path $dir 'Cookies') `
          -Destination (Join-Path $dir "Cookies.bak-$(Get-Date -Format yyyyMMdd-HHmmss)")

第 2 步:先数,再删,再校验

-- 先取证:接近或超过 70 条就是这一类
SELECT COUNT(*) FROM cookies
 WHERE host_key LIKE '%127.0.0.1%' AND name LIKE 'dsh-auth-%';

-- 定向删除,只碰自己家的行
DELETE FROM cookies
 WHERE host_key LIKE '%127.0.0.1%' AND name LIKE 'dsh-auth-%';

-- 完整性校验
PRAGMA quick_check;

PRAGMA quick_check; 返回 ok、计数归零,就可以关库了。

第 3 步:重启应用

首次启动会重新签发 1 条新 cookie——这是正常的,说明机制还在,只是计数被清零。

第 4 步(只在你误点过「禁用第三方插件」时做):还原 profile patch

在 $DSH_HOME\profiles\desktop\ 里找 .bak-* 文件,选内容完整、体积最大的那份作还原源;内容是 [] 的小文件是"禁用后"的状态,不能用。先把当前 cordis.patch.yml 复制到 $DSH_HOME\trash\<yyyyMMdd-HHmmss>\profiles\desktop\ 当回滚点,再用还原源覆盖,最后读回校验行数、插件条目数和哈希。

别做的事:不要把 NODE_OPTIONS=--max-http-header-size=131072 当长期方案,它只是抬高天花板,cookie 照样累积;也不要在运行中的应用里删库。

7. 验证:哪些我验了,哪些没验

已验证(本机读回确认)

项结果
cookie 数量71 → 0
库完整性PRAGMA quick_check = ok
备份文件Network\Cookies.bak-2026-11-07T01-53-57-673Z,53,248 字节
应用是否恢复09:56 启动成功,patch 与 settings 被重写(文件时间戳证据)
patch 还原SHA256 与原版备份一致;298 行 / 3 个 insert 条目 / UTF-8 无 BOM
与还原源的差异仅 agent-default-model 的 2 行
其他 profileheadless、web 的 cordis.patch.yml 未改动(mtime 未变)

未验证(明说,别当成实测)

  • 应用重启后插件是否全部加载:没做。这次会话就跑在这个应用里,一重启会话就断了,只能由人手动重启确认。所以"插件已还原"指的是配置文件已还原并读回校验,不等于"运行时已生效"。
  • 社区修复插件:一个都没装,没实测。
  • GitHub discussion 正文:只核验了页面可达(HTTP 200)与标题,GitHub 页面正文被截断,未逐条通读;讨论里的结论以社区教程转述为准。
  • 社区教程里的 16,186 字节推算、rc.2/rc.3/rc.4 均未修的说法:来自社区页面,本机未复现验证。
  • 约 70 次启动复发:推算值,不是实测周期。

8. 生态位对比:为什么不用现成方案

方案做法代价为什么这次没选
移走整个 Network/Cookies 重建(社区教程方法一)把 Cookies、Cookies-journal 改名,启动后自动重建清掉内嵌浏览器所有站点 cookie刚误点禁用按钮丢过配置,不想再扩大破坏面;且想保留其他站点 cookie
只删 dsh-auth-* 行(本次采用,方法二)备份 + 定向 DELETE要自己写 SQL、自己校验选了它:影响面最小、可回滚
NODE_OPTIONS=--max-http-header-size=131072(方法三)抬高 Node 请求头上限cookie 继续累积,攒到新上限原样复发;只用于抢救数据应急手段,不解决累积
MCshamrock/dsh-cookie-431(⭐7)社区修复,针对 cookie 堆积导致 431要装第三方插件、改变启动行为加包需确认;且会改变故障面、掩盖真因
divelife/dsh-http-header-limit把 maxHeaderSize 提到 256 KB同"抬高上限",不解决累积同上,且属于长期挂着的运行时改动
M0Yun/dsh-cookie-guard启动时挂后台清理器,退出即清掉上一轮及更早 cookie,只删 dsh-auth-*要装插件思路最接近"定向清理",但安装需确认;本次只用一次 SQL 就解决了

三个社区仓库都只核验了仓库页面可达与描述,未安装、未读源码、未实测,这里只作生态位对照,不作推荐背书。

9. 红线 / 速查表

  1. 不要在应用运行时动 cookie 库——WAL 可能把旧行写回,出现"删了没生效"。
  2. 不要反复点 Restart——点一次多一条 cookie,越点越糟;9 次崩溃日志完全一致就是这么来的。
  3. 不要误点「Disable third-party plugins, back up profile patch, and restart」——它不清 cookie,只清空 profile patch,会额外制造一次配置还原工作。
  4. 不要往系统日志 / 显卡驱动方向排查——WER 里的旧 dump 重复上报与 NVDisplay.Container 的 APPCRASH 都是噪音。
  5. 清理前一定先备份;确认应用正常后备份可删,留在 Network\ 目录也不影响运行。
  6. 清理 ≠ 根治——约 70 次启动(通常 1~2 个月)后会复发,届时照第 6 节再清一次。

10. 结语:一行流复盘、链接与 credit

一行流:09:26 崩溃 → 09:27~09:41 禁用插件 / 反复重启的弯路 → 09:53 备份并删 71 条 cookie → 09:56 应用恢复 → 10:07 还原 298 行插件配置 → 10:09 留档 → 12:42 联网核验链接并写这篇。

10.1 相关 GitHub Issue / Discussion(本次逐条核验)

类型链接说明
官方仓库deepseek-ai/deepseek-harnessEverything is a Plugin,TypeScript,MIT,has_discussions = true
Discussion#10831Startup fails with "Web authentication failed": 本地 dsh-auth-* cookie 每次重启累积
Discussion#10828Desktop fails to start after ~70 launches:实测边界正好 16,384 字节
Discussion#11148桌面端启动失败:Web authentication failed 根因分析(本次直接打开,HTTP 200)
Discussion#11366rc.2 / rc.3 均稳定复现,约 70 次启动后必然失败
Discussion#11408建议 connectDesktopWelcome 抛错时带上 HTTP 状态码
社区教程dsh-plugin.org:cookie 431 怎么修2026-10-30,含三种恢复路径与防复发改法
社区修复MCshamrock/dsh-cookie-431⭐7,针对 cookie 堆积导致 431
社区修复divelife/dsh-http-header-limit把 maxHeaderSize 提到 256 KB
社区修复M0Yun/dsh-cookie-guard启动时后台清理,只删 dsh-auth-*
桌面端anywhere-labs/dsh-desktop社区桌面端,"桌面本身也是插件"
插件市场dshplugin/dsh-plugin-hub社区维护的非官方插件市场仓库
官方产品页deepseek.com/en/harness产品入口
桌面端站dshdesktop.cnDSH Desktop 站点

关于"8 个 discussion"的更正:此前的排查记录里记了 8 个编号(#10716、#11215、#11408、#11474、#11617、#11758、#11965、#11968),本次联网只核实到其中 #11408 确实对应本问题;上表另外 4 个是从社区教程的来源清单里核到的。其余 7 个编号本次未独立核实,所以不贴成可点链接。教训很实在:引用 issue 编号一定要落到能打开的完整地址上,否则复盘文档里的"8 个讨论"只是个数字,不是证据。

另有检索结果里出现过 B 站视频 BV1Q1xA6bEiw 与 CSDN 排查实录,本次未逐条打开,仅列作线索。

10.2 License 与作者 credit

  • 官方仓库 deepseek-ai/deepseek-harness:MIT License(GitHub API license.spdx_id = MIT 核实),作者 deepseek-ai。
  • 社区教程 dsh-plugin.org:站点自述为社区维护、与 DeepSeek AI 无隶属关系的非官方项目,作者署名「DeepSeek Plugin 插件市场」。
  • 三个社区修复仓库作者分别为 MCshamrock、divelife、M0Yun;license 以各仓库页面为准,本次未逐一核对。
  • 桌面端仓库作者 anywhere-labs。
  • 本文与故障截图:本人实践复盘;截图为本机弹窗,未做任何外部上传。

报错文案把 431 伪装成认证失败,最贵的不是那 71 条 cookie,是它让人在账号、密钥、系统日志上白转的半小时——先看状态码,再猜原因。


原文首发:www.firstsaofan.top

本文首发于我的个人博客,其他平台为同步发布。若样式丢失或图片不显示,请到站内阅读完整版。

https://www.firstsaofan.top/