đź•’ June 23, 2025
Improve your Airflow failure emails with simple templates and customizable callbacks—engineer-friendly and easy to extend. GitHub repo
Default Airflow alert emails are basic and lack key context. With minimal setup, you can:
This approach uses Airflow’s built-in support for custom subject and HTML email templates.
email_body_template.html
– styled jinja-powered HTML alert bodyemail_subject_template.html
– dynamic subject lineIn airflow.cfg
:
[email]
html_content_template = /path/to/email_body_template.html
subject_template = /path/to/email_subject_template.html
Or as environment variables:
AIRFLOW__EMAIL__HTML_CONTENT_TEMPLATE=/path/to/email_body_template.html
AIRFLOW__EMAIL__SUBJECT_TEMPLATE=/path/to/email_subject_template.html
On task failure, it uses this subject template:
{% if task_instance.try_number > task.retries %}
🚨 [Airflow Alert] FINAL FAILURE ❌ — {{ dag.dag_id }}.{{ task.task_id }} | Exec: {{ execution_date }}
{% else %}
⚠️ [Airflow Alert] RETRY {{ task_instance.try_number }}/{{ task.retries + 1 }} — {{ dag.dag_id }}.{{ task.task_id }} | Exec: {{ execution_date }}
{% endif %}
For more control and richer alerts (e.g., run history, recovery tips), use a custom on_failure_callback
.
dags/utils/email_body_template_callback.html
– advanced HTML templatedags/utils/email_callback.py
– Python callback that renders and sends the emaildags/failure_test_dag_callback.py
– sample DAG using the callbackAlerts look like this when powered by the custom callback:
Clear and contextual alerts aren’t just a “nice-to-have” — they’re essential for fast recovery, reliable systems, and a happier on-call experience.
If you’re setting up alerts for an engineering team:
Want to try it out?
→ Explore the GitHub repo
→ Contributions and suggestions welcome!