XBSTACK
小白 / Xiaobai

小白 / Xiaobai

开发者 · 产品构建者

持续构建 AI 工程系统、开发者工具与长期数字资产。

关于作者与 XBSTACK →
n8n 2.36.6 关闭成功执行保存后 finished false status running 的 Zombie Execution A/B 实测

n8n 执行成功却一直 Running:关闭成功执行保存后 Zombie Execution 怎么解决?

n8n execution stuck running:2.36.6 生产 Webhook 已返回 200,execution_entity 却仍 status=running。本文用 SQLite A/B 复现 Zombie Execution,并给出验证 SQL、临时规避和 Issue #37040 状态。

发布 · 2026-08-297 分钟阅读XBSTACK 原创
#n8n#Workflow#Troubleshooting#Zombie Execution#Self-hosted#Docker#SQLite

如果你的 n8n production Webhook 已经返回 HTTP 200,业务动作也执行完了,但数据库里的这条 execution 过了很久仍然是:

finished = false
status = running
stoppedAt = NULL

先别把问题当成“节点还没跑完”或者“Task Runner 卡死”。我在官方 n8nio/n8n:2.36.6 上做了最小 A/B:同一实例、同一个 SQLite、同样的 Webhook → Set → No Operation 三节点工作流,唯一只改 Save successful production executions

结果很直接:设成 Do not SavesaveDataSuccessExecution=none)时,Webhook 已经返回 200,但 execution_entity 仍留下 finished=0 / status=running / stoppedAt=NULL;控制组改成 Saveall)后,同一工作流正常写成 finished=1 / status=success,并且 stoppedAt 有完整结束时间。

n8n 官方仓库的 Issue #37040 在 2026 年 8 月 25 日报告了同一个现象,环境是 n8n 2.36.6 + PostgreSQL + regular execution mode。截至本文发布时,该 Issue 仍是 Open、已进入内部 Linear 跟踪,没有关联修复 PR。也就是说,这不是“SQLite 数据库偶尔脏了”这么简单;同时也不能反过来说所有 running execution 都属于这个 Bug。

Webhook 已返回 200、执行逻辑已成功,但 execution state 仍保持 running 的矛盾状态示意

先判断是不是本文这个 Zombie Execution

这个问题最容易误判,因为 UI 或业务侧看起来“工作流已经完成”,数据库却认为它还在 running。要按本文继续排查,最好同时满足下面几个特征:

  1. 触发的是 production execution,例如生产 Webhook;
  2. Webhook/业务动作已经成功完成,而不是节点真的停在某一步;
  3. 工作流设置里 Save successful production executionsDo not Save
  4. execution_entity 对应记录是 finished=falsestatus=runningstoppedAt 为空;
  5. 同类成功执行会不断积累,而不是稍后自己变成 success。

如果你的场景是 runData 一直为空、节点压根没开始、Code 节点报 Task request timed out、Schedule Trigger 不派发,或者容器重启后工作流才恢复,那么搜索词虽然也可能是“n8n stuck running”,但根因可能完全不同。比如另一个公开 Issue #36886 描述的是实际执行路径挂住,而本文验证的是工作流已经跑完,最终状态没有被正确关闭

我怎样复现:只改一个保存选项

为了把变量压到最低,我没有用 AI Agent、数据库节点、外部 API 或复杂表达式,只建两个三节点工作流:

Production Webhook
      ↓
Set { ok: true }
      ↓
No Operation

两个 workflow 的 n8n 版本、实例、数据库和节点完全相同。唯一变量是:

实验组:saveDataSuccessExecution = none
控制组:saveDataSuccessExecution = all

两条生产 Webhook 都返回:

HTTP/1.1 200 OK

{"message":"Workflow was started"}

然后直接读取 n8n 的 SQLite execution_entity

SELECT id,
       workflowId,
       finished,
       status,
       mode,
       startedAt,
       stoppedAt,
       storedAt,
       jsonSizeBytes
FROM execution_entity
ORDER BY id DESC;

得到:

workflowId                 finished  status   stoppedAt
-------------------------  --------  -------  -----------------------
xbstackZombieControl2366   1         success  2026-08-29 02:10:30.826
xbstackZombie2366          0         running  NULL

n8n 2.36.6 Save successful executions 为 none 与 all 时的 Zombie Execution A/B 对照

这组对照排除了“Webhook 本身没成功”“复杂 workflow 某个节点卡住”“两个版本行为不同”等干扰。至少在这台 n8n 2.36.6 SQLite 实例里,把成功执行从 none 改成 all,就同时改变了 execution row 是否正常结束。

完整可导入 workflow、原始 SQL 结果和版本矩阵已经放在 GitHub 公开最小复现资产

为什么这比“UI 还显示 Running”更严重

如果只是某个前端页面没有刷新,影响通常有限。但这里的问题发生在 execution_entity 的持久化状态:

finished = false
status = running
stoppedAt = NULL

这会让数据库层仍把这次执行描述成“没有正常结束”。上游 #37040 的报告者把它称为 zombie executions,并指出这些记录会持续累积。

真正需要警惕的是它可能干扰:

  • running execution 数量判断;
  • 执行历史和监控查询;
  • pruning/retention 对异常状态记录的处理;
  • 运维脚本判断实例是否仍有未完成任务;
  • 数据库体积和历史执行治理。

因此如果你发现工作流已经成功,但 running 记录越来越多,不应该只刷新浏览器或者忽略 UI。

当前最安全的临时规避

截至 2026 年 8 月 29 日,#37040 还没有公开修复 PR,所以我不会写“升级到某个版本就好了”。当前我能验证的规避只有一个:

如果你的隐私、存储和合规策略允许,暂时把 Save successful production executions 从 Do not Save 改回 Save,并配合 execution pruning 控制留存。

原因不是理论推断,而是本文 A/B 控制组已经直接验证:saveDataSuccessExecution=all 时,同一个三节点生产 Webhook 会正常 finalise。

但这不是永久修复。启用成功执行保存会增加 execution 数据量,因此还要结合你的保留周期、pruning 配置和数据敏感性评估,尤其是 workflow 中包含用户内容、凭据派生数据或业务敏感字段时。

n8n Zombie Execution 的状态错位链路与当前可执行排障、规避步骤

不建议直接手工改 execution_entity

看到数据库里一堆:

finished = 0
status = running
stoppedAt = NULL

最直觉的操作可能是直接 UPDATE execution_entity SET ...。我不建议把它当成通用方案。

原因很简单:execution_entity 不是独立的展示表。执行状态可能与 execution data、pruning、insights、metadata 或其他生命周期逻辑相关。你只把 running 改成 success,并不能证明其他关联状态已经一致。

如果生产库已经积累大量 zombie rows,优先顺序应该是:

  1. 先完整备份数据库;
  2. 确认是不是本文这个 save-none 条件;
  3. 在隔离环境复现;
  4. 暂时启用成功执行保存验证新执行是否恢复;
  5. 对旧 zombie records 的清理策略等待 n8n 官方建议,或者在明确理解当前 schema 后再做专门迁移。

PostgreSQL 与 SQLite:目前能说到哪里

这里必须把证据边界说清楚。

上游 #37040 的报告环境是 PostgreSQL。我的本地 A/B 使用 SQLite,也复现出相同的:

finished = false
status = running
stoppedAt = NULL

这说明目前至少不能把它归因成“PostgreSQL 特有写入问题”。但我本机没有完成 PostgreSQL 独立复现,因为拉取 postgres:16-alpine 时 Docker Hub 连续出现 TLS/registry timeout。

因此当前最稳妥的表述是:

  • PostgreSQL:有官方仓库 Issue 的真实用户报告;
  • SQLite:有 XBSTACK 独立 A/B 实测;
  • 共同点:n8n 2.36.6 + 成功执行不保存;
  • 根因:官方尚未公开最终修复说明,不能自行断言具体代码行。

修复发布后应该怎样回归

等 #37040 关联 PR 或发布版本后,不要只看 changelog 就直接认为问题结束。用完全相同的最小工作流再跑一次:

Webhook → Set → No Operation
saveDataSuccessExecution = none

然后确认数据库必须满足:

不再残留 finished=0/status=running/stoppedAt=NULL 的成功执行

同时再跑 saveDataSuccessExecution=all 控制组,确保正常保存成功执行的行为没有回归。

我已经把两个 workflow JSON、原始结果和版本矩阵公开,后续官方修复出来后会继续用同一组 fixture 更新,而不是换一个新 workflow 得出不可比结果。

结论

如果你的 n8n 生产工作流已经实际成功,但 execution 长期卡在 running,并且 finished=false / stoppedAt=NULL先检查 Save successful production executions 是否设成 Do not Save

在 n8n 2.36.6 上,我的 SQLite A/B 与官方 PostgreSQL Issue 指向同一个异常边界:成功执行不保存时,execution row 可能没有完成最终状态收尾。当前没有公开正式修复,最稳妥的临时方案是根据数据留存要求评估是否启用成功执行保存,并配合 pruning,而不是直接批量改数据库状态。

相关排障:

专题入口 / AI Workflow Hub

继续按 n8n 生产排障链路读

自托管、Queue Mode、Webhook、错误处理和案例文统一沉淀到 Workflow 专题页:部署文做主力页,案例文做长尾页,对比文承接工具选择流量。

继续阅读

返回专题 →
n8n Code 节点报 Task request timed out 怎么解决?Task Runner 未匹配排查实测n8n Code 节点报 Task request timed out / not matched to a runner?实测 n8n 2.37.1 external runner,区分等待 Runner 的 request timeout 与 JavaScript 执行超时,并给出 Cloud/self-hosted 排查。Self-hosted n8n 部署指南:Docker Compose、Postgres、VPS 与 NAS 生产基线self-hosted n8n:自托管 n8n 怎么部署才稳定?本文给出 Docker Compose + Postgres 生产基线,覆盖版本固定、N8N_ENCRYPTION_KEY、WEBHOOK_URL、N8N_EDITOR_BASE_URL、反向代理、备份恢复、NAS 网络和 Queue Mode 升级边界。n8n 2.35.3 里 $json.data.sort() 为什么返回 null?Array 方法回归与修复n8n 2.35.3 的 Edit Fields 中,$json.data.sort()、splice()、fill()、copyWithin() 为什么突然返回 null?本文用官方 Docker 镜像对照 2.34.5 与 2.35.3,确认版本回归,并验证复制数组后的临时修复。n8n HTTP Request 返回 _readableState 而不是 JSON:Raw Body 为什么会变成 Stream?n8n HTTP Request 使用 Raw Body 且显式选择 JSON Response 时,为什么输出会变成 _readableState/_writableState Stream?本文用四组对照复现问题,核对 n8n 2.34.5 源码,并给出已验证的临时处理方式。

AI 工程周报

只发真正改变工程判断的变化、故障、实验和新资产。

评论与补充证据

参与讨论

问题、验证与勘误

登录后可发表评论。所有新评论先进入审核;审核期间仅评论者本人和管理员可见,通过后才公开。

登录评论 审核后公开
正在加载评论区…