shahar1 commented on issue #49920: URL: https://github.com/apache/airflow/issues/49920#issuecomment-3889427749
> @shahar1, oh, yes, I should have done it before you answered. Here is the simplest Dag built using the docs ([this](https://airflow.apache.org/docs/apache-airflow-providers-smtp/stable/_api/airflow/providers/smtp/notifications/smtp/index.html#airflow.providers.smtp.notifications.smtp.SmtpNotifier) and [this](https://airflow.apache.org/docs/apache-airflow-providers-smtp/stable/notifications/smtp_notifier_howto_guide.html)) (the real emails are replaced): > ```python > from airflow.decorators import dag, task > from airflow.providers.smtp.notifications.smtp import SmtpNotifier > > > @dag( > schedule=None, > default_args={ > "on_failure_callback": [ > SmtpNotifier( > to="to_email", > from_email="from_email", > subject="[Error] The task {{ ti.task_id }} failed", > html_content="Link to the logs: {{ ti.log_url }}", > ) > ] > }, > ) > def test_smtp_notification(): > @task > def failing_task(): > raise RuntimeError("Error!") > > failing_task() > > > test_smtp_notification() > ``` > Here are the logs: > ```bash > 2026-02-12, 07:59:28 UTC] {taskinstance.py:3336} ERROR - Task failed with exception > Traceback (most recent call last): > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/models/taskinstance.py", line 776, in _execute_task > result = _execute_callable(context=context, **execute_callable_kwargs) > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/models/taskinstance.py", line 742, in _execute_callable > return ExecutionCallableRunner( > ^^^^^^^^^^^^^^^^^^^^^^^^ > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/utils/operator_helpers.py", line 252, in run > return self.func(*args, **kwargs) > ^^^^^^^^^^^^^^^^^^^^^^^^^^ > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/models/baseoperator.py", line 424, in wrapper > return func(self, *args, **kwargs) > ^^^^^^^^^^^^^^^^^^^^^^^^^^^ > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/decorators/base.py", line 266, in execute > return_value = super().execute(context) > ^^^^^^^^^^^^^^^^^^^^^^^^ > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/models/baseoperator.py", line 424, in wrapper > return func(self, *args, **kwargs) > ^^^^^^^^^^^^^^^^^^^^^^^^^^^ > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/operators/python.py", line 238, in execute > return_value = self.execute_callable() > ^^^^^^^^^^^^^^^^^^^^^^^ > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/operators/python.py", line 256, in execute_callable > return runner.run(*self.op_args, **self.op_kwargs) > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/utils/operator_helpers.py", line 252, in run > return self.func(*args, **kwargs) > ^^^^^^^^^^^^^^^^^^^^^^^^^^ > File "/opt/airflow/dags/test_smtp_notification.py", line 21, in failing_task > raise RuntimeError("Error!") > RuntimeError: Error! > [2026-02-12, 07:59:28 UTC] {taskinstance.py:1242} INFO - Marking task as FAILED. dag_id=test_smtp_notification, task_id=failing_task, run_id=manual__2026-02-12T07:59:27.575809+00:00, execution_date=20260212T075927, start_date=20260212T075928, end_date=20260212T075928 > [2026-02-12, 07:59:28 UTC] {taskinstance.py:1580} INFO - Executing callback at index 0: SmtpNotifier > [2026-02-12, 07:59:28 UTC] {base.py:84} INFO - Retrieving connection 'smtp_default' > [2026-02-12, 07:59:28 UTC] {basenotifier.py:109} ERROR - Failed to send notification: 'NoneType' object has no attribute 'close' > Traceback (most recent call last): > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/models/taskinstance.py", line 282, in _run_raw_task > TaskInstance._execute_task_with_callbacks( > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/models/taskinstance.py", line 3184, in _execute_task_with_callbacks > result = self._execute_task(context, task_orig) > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/models/taskinstance.py", line 3208, in _execute_task > return _execute_task(self, context, task_orig) > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/models/taskinstance.py", line 776, in _execute_task > result = _execute_callable(context=context, **execute_callable_kwargs) > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/models/taskinstance.py", line 742, in _execute_callable > return ExecutionCallableRunner( > ^^^^^^^^^^^^^^^^^^^^^^^^ > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/utils/operator_helpers.py", line 252, in run > return self.func(*args, **kwargs) > ^^^^^^^^^^^^^^^^^^^^^^^^^^ > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/models/baseoperator.py", line 424, in wrapper > return func(self, *args, **kwargs) > ^^^^^^^^^^^^^^^^^^^^^^^^^^^ > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/decorators/base.py", line 266, in execute > return_value = super().execute(context) > ^^^^^^^^^^^^^^^^^^^^^^^^ > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/models/baseoperator.py", line 424, in wrapper > return func(self, *args, **kwargs) > ^^^^^^^^^^^^^^^^^^^^^^^^^^^ > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/operators/python.py", line 238, in execute > return_value = self.execute_callable() > ^^^^^^^^^^^^^^^^^^^^^^^ > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/operators/python.py", line 256, in execute_callable > return runner.run(*self.op_args, **self.op_kwargs) > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/utils/operator_helpers.py", line 252, in run > return self.func(*args, **kwargs) > ^^^^^^^^^^^^^^^^^^^^^^^^^^ > File "/opt/airflow/dags/test_smtp_notification.py", line 21, in failing_task > raise RuntimeError("Error!") > RuntimeError: Error! > During handling of the above exception, another exception occurred: > Traceback (most recent call last): > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/providers/smtp/notifications/smtp.py", line 140, in notify > smtp.send_email_smtp( > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/providers/smtp/hooks/smtp.py", line 214, in send_email_smtp > raise AirflowException("The 'smtp_client' should be initialized before!") > airflow.exceptions.AirflowException: The 'smtp_client' should be initialized before! > During handling of the above exception, another exception occurred: > Traceback (most recent call last): > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/notifications/basenotifier.py", line 107, in __call__ > self.notify(context) > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/providers/smtp/notifications/smtp.py", line 139, in notify > with self.hook as smtp: > ^^^^^^^^^ > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/providers/smtp/hooks/smtp.py", line 72, in __exit__ > self.smtp_client.close() > ^^^^^^^^^^^^^^^^^^^^^^ > AttributeError: 'NoneType' object has no attribute 'close' > ``` > I'm using the default Compose file with `Airflow=2.11.0`. If I remove the `from_email` (which is already given in the Web UI Connection tab), I get the error stated in the issue head: > ```bash > During handling of the above exception, another exception occurred: > Traceback (most recent call last): > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/notifications/basenotifier.py", line 107, in __call__ > self.notify(context) > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/providers/smtp/notifications/smtp.py", line 111, in notify > if self.hook.from_email is not None: > ^^^^^^^^^^^^^^^^^^^^ > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/providers/smtp/hooks/smtp.py", line 365, in from_email > return self.conn.extra_dejson.get("from_email") > ^^^^^^^^^ > File "/home/airflow/.local/lib/python3.12/site-packages/airflow/providers/smtp/hooks/smtp.py", line 356, in conn > raise AirflowException("The smtp connection should be loaded before!") > airflow.exceptions.AirflowException: The smtp connection should be loaded before! > ``` > > What I have already done: > - double checked the connection in the Web UI, checked that `smtp-server` (a Docker container with Mailpit) is reachable from within the worker and scheduler containers: > ```bash > (airflow)nc -zv smtp-server 1025 > Connection to smtp-server (172.18.0.3) 1025 port [tcp/*] succeeded! > ``` > - checked that the connection is correctly retrieved by Airflow: > ```python > from airflow.hooks.base import BaseHook > > conn = BaseHook.get_connection("smtp_default") > print(conn.host, conn.port, conn.extra) # Prints smtp-server 1025 {"from_email": "from_email", "timeout": 30, "retry_limit": 0, "disable_tls": true, "disable_ssl": true} > ``` > - tried `SmtpHook` directly and `with` but again got `airflow.exceptions.AirflowException: The 'smtp_client' should be initialized before!`: > ```python > def failure_callback(context): > with SmtpHook(smtp_conn_id="smtp_default") as hook: > hook.send_email_smtp( > to="to_email", > from_email="from_email", > subject="Test failure", > html_content="Body", > ) > > @dag( > schedule=None, > default_args={ > "on_failure_callback": [ > failure_callback > ] > }, > ) > ... > ``` Thanks, reopened the issue. Feel free to investigate and contribute a fix if you want, otherwise it will wait for someone else to do that :) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
