Skip to content

Fix SMTP connection from_email being ignored by email_on_failure and …#69271

Open
bramhanandlingala wants to merge 4 commits into
apache:mainfrom
bramhanandlingala:fix/#69262
Open

Fix SMTP connection from_email being ignored by email_on_failure and …#69271
bramhanandlingala wants to merge 4 commits into
apache:mainfrom
bramhanandlingala:fix/#69262

Conversation

@bramhanandlingala

Copy link
Copy Markdown
Contributor

Summary

_send_error_email_notification (used for email_on_failure / email_on_retry) resolved [email] from_email before constructing SmtpNotifier, so SmtpNotifier's own connection-extra fallback branch never ran. This meant the SMTP connection's from_email extra was silently ignored whenever [email] from_email was set — or even when it wasn't, since a hardcoded airflow@airflow fallback was passed in regardless.

This PR moves from_email precedence resolution into SmtpNotifier itself:

  1. Explicit from_email argument (if passed directly to SmtpNotifier)
  2. SMTP connection extra from_email
  3. [email] from_email config
  4. Hardcoded airflow@airflow default

task_runner.py now passes from_email=None to SmtpNotifier and lets it resolve precedence, instead of resolving [email] from_email upfront and locking out the connection-extra check.

Root cause

# before (task_runner.py)
from_email=conf.get("email", "from_email", fallback="airflow@airflow"),

Since this was never None, SmtpNotifier._build_email_content's if self.from_email is None: branch — which checks the SMTP connection's from_email extra — could never execute.

Fix

  • providers/smtp/src/airflow/providers/smtp/notifications/smtp.py: _build_email_content now falls back through connection extra → [email] from_email config → hardcoded default, instead of raising when the connection extra is unset.
  • task-sdk/src/airflow/sdk/execution_time/task_runner.py: passes from_email=None so the notifier's own resolution logic runs.

Testing

  • Added 3 new unit tests in test_smtp.py covering all precedence combinations (connection-only, config-only, connection-over-config, neither-set-default).
  • Updated 3 existing assertions in test_task_runner.py to reflect that from_email resolution now happens inside SmtpNotifier, not task_runner.py.

Fixes #69262

@SameerMesiah97 SameerMesiah97 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.

Only one clarification. Looks good otherwise.

@@ -2058,50 +1951,13 @@ def _send_error_email_notification(
to=to_emails,
subject=subject,
html_content=html_content,
from_email=conf.get("email", "from_email", fallback="airflow@airflow"),
from_email=None,

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.

Are there any other callers that still resolve from_email themselves before constructing the notifier? Please check.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Hi @SameerMesiah97

Good question — I checked. SmtpNotifier is only constructed in one production call site outside its own module, which is _send_error_email_notification in task_runner.py, and that's already updated in this PR to pass from_email=None. I didn't find any other operator or utility in the repo that resolves from_email from config before building the notifier, so this should cover all callers.

@stephsi

stephsi commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Hello @bramhanandlingala!

Thanks for creating a PR related to my issue. I think your suggested changes make sense overall.

I have one suggestion though:
Your three test cases now cover config-only, connection-over-config and neither-set-default , I would argue that you should also adjust the already existing test case connection-only to the style of your three created test cases, so it is more clear that these four test cases belong together. Also add a comment at the beginning to the already existing test case similar to your three test cases.

I also have some wording suggestions for the test comments, but these are maybe more personal preferences.

@@ -211,6 +211,70 @@ def test_notifier_with_nondefault_connection_extra(
**DEFAULT_EMAIL_PARAMS,
)

@mock.patch("airflow.providers.smtp.notifications.smtp.SmtpHook")
def test_notifier_from_email_falls_back_to_config(self, mock_smtphook_hook, create_dag_without_db):
"""When from_email is unset and the connection defines none, `[email] from_email` config is used."""

@stephsi stephsi Jul 8, 2026

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.

Suggested change
"""When from_email is unset and the connection defines none, `[email] from_email` config is used."""
"""When config [email] from_email is set and the SMTP connection extra `from_email` is NOT set, `[email] from_email` config is used."""

I assume unset was a typing mistake as this is the test case where the config is set and the connection extra field is not set.

@bramhanandlingala

Copy link
Copy Markdown
Contributor Author

Hi @stephsi

Good catch, thanks — that was indeed a typo, "unset" should've said the connection extra is not set. Fixed in the latest commit using your suggested wording exactly. I've also added a matching docstring to test_notifier_with_nondefault_connection_extra so all four tests (connection-only, config-only, connection-over-config, neither-set-default) are now consistent in style, per your other comment. Happy to take any further wording suggestions if you have them.

@potiuk potiuk added the ready for maintainer review Set after triaging when all criteria pass. label Jul 18, 2026
@bramhanandlingala

bramhanandlingala commented Jul 19, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @potiuk

@stephsi, @bugraoz93, @choo121600, @ephraimbuddy, @henry3260, @jason810496, @rawwar, @kaxil, @ashb, @amoghrajesh, @Lee-W
Request You All, please review and Merge as need for this fix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SMTP connection configuration from_email is ignored by email_on_failure and email_on_retry

4 participants