n8n - 💡(How to fix) Fix GET /api/v1/executions?status=crashed returns records whose stored status is success/error/waiting (n8n 2.13.3, queue mode)

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

The execution list endpoint's status=crashed filter does not behave as a status filter. Records returned have a per-id status of success, error, or waiting when re-fetched via GET /api/v1/executions/{id}. The list filter appears to project a different (likely internal worker-state) field rather than the final stored status.

This causes monitoring scripts that consume the list endpoint to fire phantom crash alerts indistinguishable from real worker-OOM / SIGTERM events.

Error Message

The execution list endpoint's status=crashed filter does not behave as a status filter. Records returned have a per-id status of success, error, or waiting when re-fetched via GET /api/v1/executions/{id}. The list filter appears to project a different (likely internal worker-state) field rather than the final stored status. | 1 | error | no |

Root Cause

Monitoring scripts and CI alerts that consume the list endpoint cannot distinguish phantom crashes from real worker kills. In our project this generated repeat phantom alert clusters of 100-250 records, costing approximately 1.5 hours of triage time across two sessions. The fix on our side is per-id re-validation, which works but defeats the purpose of having a status filter on the list endpoint.

If the intended behavior is "list executions that transiently entered a crashed state during their lifecycle (regardless of final stored status)", that should be documented — the status field name is then ambiguous between "final stored status" (per-id) and "ever-was-in-this-state" (list). Most operators will read it as the former.

Code Example

# List filter says these are "crashed":
curl -s -H "X-N8N-API-KEY: $KEY" "$HOST/api/v1/executions?status=crashed&limit=10" | jq '.data[].id'

# Re-fetch each by id — status differs:
for id in <ids-from-above>; do
  curl -s -H "X-N8N-API-KEY: $KEY" "$HOST/api/v1/executions/$id" | jq '{id, status, finished, stoppedAt}'
done
RAW_BUFFERClick to expand / collapse

Summary

The execution list endpoint's status=crashed filter does not behave as a status filter. Records returned have a per-id status of success, error, or waiting when re-fetched via GET /api/v1/executions/{id}. The list filter appears to project a different (likely internal worker-state) field rather than the final stored status.

This causes monitoring scripts that consume the list endpoint to fire phantom crash alerts indistinguishable from real worker-OOM / SIGTERM events.

Reproduction (n8n 2.13.3, queue mode, postgres backend)

# List filter says these are "crashed":
curl -s -H "X-N8N-API-KEY: $KEY" "$HOST/api/v1/executions?status=crashed&limit=10" | jq '.data[].id'

# Re-fetch each by id — status differs:
for id in <ids-from-above>; do
  curl -s -H "X-N8N-API-KEY: $KEY" "$HOST/api/v1/executions/$id" | jq '{id, status, finished, stoppedAt}'
done

Sample evidence (collected 2026-05-04)

15 executions sampled at random from the list response with ?status=crashed&limit=250. Per-id re-fetch:

nper-id statusmatch list crashed claim?
13successno
1errorno
1waitingno
0crashedn/a

Six reference IDs (49807, 49808, 49809, 50046, 50047, 50048) all return status=success, finished=true when fetched individually. The list endpoint had reported them as crashed.

Why this matters

Monitoring scripts and CI alerts that consume the list endpoint cannot distinguish phantom crashes from real worker kills. In our project this generated repeat phantom alert clusters of 100-250 records, costing approximately 1.5 hours of triage time across two sessions. The fix on our side is per-id re-validation, which works but defeats the purpose of having a status filter on the list endpoint.

If the intended behavior is "list executions that transiently entered a crashed state during their lifecycle (regardless of final stored status)", that should be documented — the status field name is then ambiguous between "final stored status" (per-id) and "ever-was-in-this-state" (list). Most operators will read it as the former.

Suggested resolution (in priority order)

  1. Fix the list filter to project the same status field as the per-id endpoint. The two should always agree for the same execution id.
  2. OR add a separate query parameter (e.g. lifecycleStatus=crashed) for the transient-state semantics, and have status=crashed project the stored final status.
  3. OR at minimum, document the divergence prominently in the public REST API reference so operators don't trust list-filter output for alerting.

Environment

  • n8n version: 2.13.3
  • Mode: queue (with task runner)
  • Database: Postgres
  • OS: Linux (docker container)

Related

This was triaged in our own incident tracker as INC-026. Happy to share more sample IDs / timestamps / database state if useful.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

n8n - 💡(How to fix) Fix GET /api/v1/executions?status=crashed returns records whose stored status is success/error/waiting (n8n 2.13.3, queue mode)