Skip to content

Abandon (not crash) evicted flow runs when Kubernetes owns retries#22622

Open
chuqCTC wants to merge 1 commit into
PrefectHQ:mainfrom
chuqCTC:fix/22620-abandon-sigterm-backofflimit
Open

Abandon (not crash) evicted flow runs when Kubernetes owns retries#22622
chuqCTC wants to merge 1 commit into
PrefectHQ:mainfrom
chuqCTC:fix/22620-abandon-sigterm-backofflimit

Conversation

@chuqCTC

@chuqCTC chuqCTC commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

closes #22620

The bug

On a Kubernetes pool with backoffLimit > 0, an evicted pod gets a SIGTERM and the engine marks the run Crashed. But Kubernetes then starts a fresh pod for the same Job and runs the flow again, so a run that was already terminal comes back and runs twice.

The fix

Add an abandon SIGTERM mode. When backoffLimit > 0, the worker sets PREFECT_FLOW_RUN_EXECUTE_SIGTERM_BEHAVIOR=abandon, and in that mode the engine exits on SIGTERM without setting any state. The run stays running while Kubernetes retries the pod. If every attempt is evicted, the worker still marks the run Crashed once the retries are used up.

Prefect's own reschedule (backoffLimit == 0) and Kubernetes Job retries stay mutually exclusive, as before.

Worth noting

  • An unset backoffLimit now behaves like abandon rather than crashing. Kubernetes defaults it to 6, so retries really do happen.
  • This also fixes reschedule mode for async flows, where a delayed SIGTERM could arrive as a cancellation and crash the run instead of leaving it in AwaitingRetry.

@chuqCTC
chuqCTC force-pushed the fix/22620-abandon-sigterm-backofflimit branch 3 times, most recently from 1552afd to 4bdc7c1 Compare July 24, 2026 21:05
@chuqCTC
chuqCTC marked this pull request as ready for review July 24, 2026 21:07
@chuqCTC
chuqCTC force-pushed the fix/22620-abandon-sigterm-backofflimit branch from 4bdc7c1 to c368e70 Compare July 24, 2026 21:08

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4bdc7c19bf

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/prefect/flow_engine.py
@codspeed-hq

codspeed-hq Bot commented Jul 24, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 8 untouched benchmarks
⏩ 1 skipped benchmark1


Comparing chuqCTC:fix/22620-abandon-sigterm-backofflimit (b6df6d9) with main (d2d873b)

Open in CodSpeed

Footnotes

  1. 1 benchmark was skipped, so the baseline result was used instead. If it was deleted from the codebase, click here and archive it to remove it from the performance reports.

Closes PrefectHQ#22620.

With a Kubernetes work pool at backoffLimit > 0, a SIGTERM (eviction)
made the in-pod engine finalize the run Crashed via handle_crash, but
Kubernetes then retried the Job and re-ran the flow, so the run left a
terminal state and executed twice.

Add an "abandon" SIGTERM behavior: when backoffLimit > 0 the worker sets
PREFECT_FLOW_RUN_EXECUTE_SIGTERM_BEHAVIOR=abandon, and the engine bubbles
the raw SIGTERM without proposing a state. The run stays non-terminal
while Kubernetes retries the pod; if retries are exhausted the worker's
non-zero-exit crash proposal finalizes it. Prefect reschedule and k8s
Job backoff remain mutually exclusive.

A raw SIGTERM can reach an async flow as a cancellation rather than a
TerminationSignal, so the bubble is gated on a latch set by the SIGTERM
handler to avoid abandoning ordinary cancellations (e.g. flow timeouts).
@chuqCTC
chuqCTC force-pushed the fix/22620-abandon-sigterm-backofflimit branch from c368e70 to b6df6d9 Compare July 24, 2026 21:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A Crashed flow run is restarted by Kubernetes Job retry (backoffLimit > 0)

1 participant