Skip to content

Respect retries when a deferrable trigger ends a task with TaskFailedEvent - #69821

Merged
vatsrahul1001 merged 3 commits into
apache:mainfrom
hkc-8010:fix/deferred-task-failed-event-respects-retries
Aug 5, 2026
Merged

Respect retries when a deferrable trigger ends a task with TaskFailedEvent#69821
vatsrahul1001 merged 3 commits into
apache:mainfrom
hkc-8010:fix/deferred-task-failed-event-respects-retries

Conversation

@hkc-8010

@hkc-8010 hkc-8010 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Summary

When a deferrable operator's trigger yields a terminal TaskFailedEvent, the task was always marked failed and its on_failure_callback ran, even when the task still had retries remaining. A worker-side failure with retries left instead goes up_for_retry and runs on_retry_callback. This makes trigger-driven failures behave the same way.

The BaseTaskEndEvent handler in airflow-core/src/airflow/models/trigger.py now, for a FAILED event, loads the serialized task and routes through TaskInstance.handle_failure(), the same path the scheduler executor-event handling has used since #56586. handle_failure sets up_for_retry or failed based on retry-eligibility and fires the on_task_instance_failed listener, failure metrics, and a Log entry. The callback request now carries the resolved task_callback_type so the DAG processor runs on_retry_callback vs on_failure_callback correctly. TaskSuccessEvent and TaskSkippedEvent are unchanged.

closes: #69819

Changes

  • airflow-core/src/airflow/models/trigger.py: route trigger-emitted failures through handle_failure, thread the retry-aware task_callback_type into the callback, and skip the xcom push on the retry path.
  • airflow-core/tests/unit/models/test_trigger.py: new parametrized test covering the retry-eligible case (up_for_retry + on_retry_callback + on_task_instance_failed listener) and the exhausted case (failed + on_failure_callback); the existing end-event test now sets a realistic start_date (a deferred task has already run).
  • airflow-core/newsfragments/69821.bugfix.rst.

Testing

  • pytest airflow-core/tests/unit/models/test_trigger.py (39 passed).
  • Confirmed the new test fails on main (the task stays failed and the callback is routed as a failure) and passes with this change.

This change was written with AI assistance (Claude); the author reviewed the diff and reproduction.

…Event

When a deferrable operator's trigger yields a terminal TaskFailedEvent, the task
was always marked failed and on_failure_callback ran, even with retries remaining.
A worker-side failure with retries left instead goes up_for_retry and runs
on_retry_callback. Route trigger-emitted failures through TaskInstance.handle_failure
(the path the scheduler has used since apache#56586) so retry-eligibility is respected and
the callback runs on_retry_callback vs on_failure_callback accordingly.

closes: apache#69819

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@hkc-8010
hkc-8010 force-pushed the fix/deferred-task-failed-event-respects-retries branch from 4017af8 to 5dfb1ce Compare July 13, 2026 11:17
@hkc-8010
hkc-8010 marked this pull request as ready for review July 13, 2026 12:17
@hkc-8010
hkc-8010 requested review from XD-DENG and ashb as code owners July 13, 2026 12:17
@eladkal eladkal added this to the Airflow 3.3.1 milestone Jul 15, 2026
@eladkal eladkal added type:bug-fix Changelog: Bug Fixes backport-to-v3-3-test Backport to v3-3-test labels Jul 15, 2026
@potiuk potiuk added the ready for maintainer review Set after triaging when all criteria pass. label Jul 15, 2026
Comment thread airflow-core/src/airflow/models/trigger.py Outdated
Comment thread airflow-core/tests/unit/models/test_trigger.py Outdated
@hkc-8010
hkc-8010 requested a review from kaxil August 2, 2026 18:45

@amoghrajesh amoghrajesh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code looks ok, but I have a qn, seems to be spillover from past version of the PR

Comment thread airflow-core/src/airflow/models/trigger.py Outdated
@eladkal
eladkal requested a review from amoghrajesh August 4, 2026 16:59
@vatsrahul1001
vatsrahul1001 merged commit dd1f84a into apache:main Aug 5, 2026
78 checks passed
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Backport failed to create: v3-3-test. View the failure log Run details

Note: As of Merging PRs targeted for Airflow 3.X
the committer who merges the PR is responsible for backporting the PRs that are bug fixes (generally speaking) to the maintenance branches.

In matter of doubt please ask in #release-management Slack channel.

Status Branch Result
v3-3-test Commit Link

You can attempt to backport this manually by running:

cherry_picker dd1f84a v3-3-test

This should apply the commit to the v3-3-test branch and leave the commit in conflict state marking
the files that need manual conflict resolution.

After you have resolved the conflicts, you can continue the backport process by running:

cherry_picker --continue

If you don't have cherry-picker installed, see the installation guide.

vatsrahul1001 added a commit that referenced this pull request Aug 5, 2026
…Event (#69821) (#71163)

* Respect retries when a deferrable trigger ends a task with TaskFailedEvent

When a deferrable operator's trigger yields a terminal TaskFailedEvent, the task
was always marked failed and on_failure_callback ran, even with retries remaining.
A worker-side failure with retries left instead goes up_for_retry and runs
on_retry_callback. Route trigger-emitted failures through TaskInstance.handle_failure
(the path the scheduler has used since #56586) so retry-eligibility is respected and
the callback runs on_retry_callback vs on_failure_callback accordingly.

closes: #69819



* Preserve retry history for trigger-ended deferred failures

* Fix stale trigger callback comment

---------


(cherry picked from commit dd1f84a)

Co-authored-by: Hemkumar Chheda <95332229+hkc-8010@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
vatsrahul1001 added a commit that referenced this pull request Aug 5, 2026
…Event (#69821) (#71163)

* Respect retries when a deferrable trigger ends a task with TaskFailedEvent

When a deferrable operator's trigger yields a terminal TaskFailedEvent, the task
was always marked failed and on_failure_callback ran, even with retries remaining.
A worker-side failure with retries left instead goes up_for_retry and runs
on_retry_callback. Route trigger-emitted failures through TaskInstance.handle_failure
(the path the scheduler has used since #56586) so retry-eligibility is respected and
the callback runs on_retry_callback vs on_failure_callback accordingly.

closes: #69819



* Preserve retry history for trigger-ended deferred failures

* Fix stale trigger callback comment

---------


(cherry picked from commit dd1f84a)

Co-authored-by: Hemkumar Chheda <95332229+hkc-8010@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:Triggerer backport-to-v3-3-test Backport to v3-3-test ready for maintainer review Set after triaging when all criteria pass. type:bug-fix Changelog: Bug Fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Deferrable task that ends via TaskFailedEvent ignores retries and always runs on_failure_callback

6 participants