Apache Airflow version
3.2.2
If "Other Airflow 2 version" selected, which one?
No response
What happened?
When a DAG is updated (any code change that produces a new serialized_dag row), DeadlineAlert records are not created for the new serialized_dag. All subsequent dag_runs for that DAG silently produce no Deadline entries and never fire deadline callbacks.
Root cause
In SerializedDagModel.write_dag() (airflow/models/serialized_dag.py), when the deadline definition hasn't changed between versions, _try_reuse_deadline_uuids() returns the existing UUIDs and the code sets:
# serialized_dag.py ~line 646-651
if deadline_uuid_mapping is not None:
# All deadlines matched — reuse the UUIDs to preserve hash.
# Clear the mapping since the alert rows already exist in the DB;
# no need to delete and recreate identical records.
dag.data["dag"]["deadline"] = existing_deadline_uuids
deadline_uuid_mapping = {}
Then in the new serialized_dag creation path (when has_task_instances=True):
# line 734
cls._create_deadline_alert_records(new_serialized_dag, deadline_uuid_mapping)
Since deadline_uuid_mapping = {}, _create_deadline_alert_records returns immediately (if not uuid_mapping: return) — the new serialized_dag gets no deadline_alert rows.
When a dag_run is created, definitions/dag.py queries:
SELECT * FROM deadline_alert WHERE serialized_dag_id = <new_serialized_dag_id>
Finds nothing → no Deadline row inserted → triggerer never fires the callback.
The {} optimization is correct for the in-place UPDATE path (same serialized_dag row, existing deadline_alert records stay valid). It is wrong for the INSERT path (new row, no deadline_alert records exist for the new serialized_dag_id).
What you think should happen instead?
deadline_alert records should be created for every new serialized_dag row, regardless of whether the deadline definition changed.
Suggested fix
In _create_deadline_alert_records, when the new serialized_dag path is taken (INSERT, not UPDATE), generate new UUIDs and create new deadline_alert records even when the deadline definition matches the previous version. The empty-mapping optimization should only apply to the in-place UPDATE path (lines 691–713).
How to reproduce
- Deploy a DAG with a
DeadlineAlert — verify a deadline_alert record is created
- Make any code change to the DAG file that produces a new
dag_version (e.g. add a comment) without changing the deadline definition
- Wait for git-sync to pick up the new version
- Trigger a
dag_run and wait past the deadline
- No alert fires; the
deadline table has no row for this run
Operating System
N/A
Versions of Apache Airflow Providers
N/A
Deployment
Other 3rd-party Helm chart
Deployment details
No response
Anything else?
No response
Are you willing to submit PR?
Code of Conduct
Apache Airflow version
3.2.2
If "Other Airflow 2 version" selected, which one?
No response
What happened?
When a DAG is updated (any code change that produces a new
serialized_dagrow),DeadlineAlertrecords are not created for the newserialized_dag. All subsequentdag_runs for that DAG silently produce noDeadlineentries and never fire deadline callbacks.Root cause
In
SerializedDagModel.write_dag()(airflow/models/serialized_dag.py), when the deadline definition hasn't changed between versions,_try_reuse_deadline_uuids()returns the existing UUIDs and the code sets:Then in the new
serialized_dagcreation path (whenhas_task_instances=True):Since
deadline_uuid_mapping = {},_create_deadline_alert_recordsreturns immediately (if not uuid_mapping: return) — the newserialized_daggets nodeadline_alertrows.When a
dag_runis created,definitions/dag.pyqueries:Finds nothing → no
Deadlinerow inserted → triggerer never fires the callback.The
{}optimization is correct for the in-place UPDATE path (sameserialized_dagrow, existingdeadline_alertrecords stay valid). It is wrong for the INSERT path (new row, nodeadline_alertrecords exist for the newserialized_dag_id).What you think should happen instead?
deadline_alertrecords should be created for every newserialized_dagrow, regardless of whether the deadline definition changed.Suggested fix
In
_create_deadline_alert_records, when the newserialized_dagpath is taken (INSERT, not UPDATE), generate new UUIDs and create newdeadline_alertrecords even when the deadline definition matches the previous version. The empty-mapping optimization should only apply to the in-place UPDATE path (lines 691–713).How to reproduce
DeadlineAlert— verify adeadline_alertrecord is createddag_version(e.g. add a comment) without changing the deadline definitiondag_runand wait past the deadlinedeadlinetable has no row for this runOperating System
N/A
Versions of Apache Airflow Providers
N/A
Deployment
Other 3rd-party Helm chart
Deployment details
No response
Anything else?
No response
Are you willing to submit PR?
Code of Conduct