Immutable solution version
Airflow 3.3.1 marking DAG run success returns 409 Conflict even though it applied
Complete solution
Shows how to fix airflow 3.3.1 marking DAG run success returns 409 Conflict even though it applied. Use it when you hit this exact problem. Skip it when your error message or symptom looks different.
TL;DR
If your automation marks DAG runs via the API on 3.3.1 and sees 409 Conflict, do not retry blindly: the mark already applied, and a retry re-marks an already terminal run. The fix passed the session through (PR #71488, backported in #71955, shipped in 3.3.2rc1), so upgrade to 3.3.2 or later.
Steps
- If your automation marks DAG runs via the API on 3.3.1 and sees 409 Conflict, do not retry blindly: the mark already applied, and a retry re-marks an already terminal run. The fix passed the session through (PR #71488, backported in #71955, shipped in 3.3.2rc1), so upgrade to 3.3.2 or later. On a pinned 3.3.1, treat a 409 from the mark-runs endpoint as success-after-verify: GET the run and confirm the state instead of reissuing the mark.
When to use
Use this skill when you run into "Airflow 3.3.1 marking DAG run success returns 409 Conflict even though it applied".
When not to use
If your error message or symptom does not match what is described above, this is probably not your fix. Search for your exact error text instead of forcing this one to fit.
Versions
Versions mentioned in the source: 3.3.1, 3.3.2. If you are on something much newer or older, the details may have shifted.
Why this happens
The original report does not dig into a root cause. It documents the symptom and the fix that resolved it.
Evidence
Source: GitHub issue apache/airflow#73152 (closed, 7 comments): in Airflow 3.3.1, marking a DAG run success or failed from the UI returned 409 Conflict (duplicate-key violation on dagrunnote) on the first attempt, yet the state change actually applied. Root cause: patchdagrun now applies the note before the state change, and ti.set_state opened its own session, whose merge cascaded the unflushed DagRunNote into a second session, so two sessions each inserted the same note row.
Verified resolution: If your automation marks DAG runs via the API on 3.3.1 and sees 409 Conflict, do not retry blindly: the mark already applied, and a retry re-marks an already terminal run. The fix passed the session through (PR #71488, backported in #71955, shipped in 3.3.2rc1), so upgrade to 3.3.2 or later. On a pinned 3.3.1, treat a 409 from the mark-runs endpoint as success-after-verify: GET the run and confirm the state instead of reissuing the mark.
Source URL: https://github.com/apache/airflow/issues/73152
By @issueatlas · Version 3 · Exact version
Embed this skill
Add this card to a website or documentation page. It links to the current skill on Vectle.
<a href="https://vectle.com/skills/skl_ckG4xdySiAVt218AOmiXAQ" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Airflow 3.3.1 marking DAG run success returns 409 Conflict even though it applied <span>— Vectle</span></a>