SSL Certificate error on SMTP Django DRF App [duplicate]

I have a Django DRF Backend that works just OK when using EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend".

But then, switching to SMTP powered by Google as:

EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
EMAIL_HOST = "smtp.gmail.com"
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = config("GMAIL_APP_HOST_USER")
EMAIL_HOST_PASSWORD = config("GMAIL_APP_HOST_PASSWORD")
DEFAULT_FROM_EMAIL = "TestApp"
ACCOUNT_EMAIL_SUBJECT_PREFIX = ""

I get a [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Basic Constraints of CA cert not marked critical

This is being tested in a Windows 11 PC.

Error details with Traceback:

Django Version: 5.2.6
Python Version: 3.13.7
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.sites',
 'django.contrib.staticfiles',
 'rest_framework',
 'rest_framework.authtoken',
 'rest_framework_simplejwt',
 'allauth',
 'allauth.account',
 'allauth.headless',
 'allauth.socialaccount',
 'allauth.socialaccount.providers.google',
 'dj_rest_auth',
 'dj_rest_auth.registration',
 'corsheaders',
 'authentication.apps.AuthenticationConfig']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'allauth.account.middleware.AccountMiddleware',
 'corsheaders.middleware.CorsMiddleware',
 'django.middleware.common.CommonMiddleware']



Traceback (most recent call last):
  File "C:\dev\myProject\venv\Lib\site-packages\django\core\handlers\exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\django\views\decorators\csrf.py", line 65, in _view_wrapper
    return view_func(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\django\views\generic\base.py", line 105, in view
    return self.dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\django\utils\decorators.py", line 48, in _wrapper
    return bound_method(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\django\views\decorators\debug.py", line 143, in sensitive_post_parameters_wrapper
    return view(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\dj_rest_auth\registration\views.py", line 47, in dispatch
    return super().dispatch(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\rest_framework\views.py", line 515, in dispatch
    response = self.handle_exception(exc)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\rest_framework\views.py", line 475, in handle_exception
    self.raise_uncaught_exception(exc)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\rest_framework\views.py", line 486, in raise_uncaught_exception
    raise exc
    ^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\rest_framework\views.py", line 512, in dispatch
    response = handler(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\rest_framework\generics.py", line 194, in post
    return self.create(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\dj_rest_auth\registration\views.py", line 68, in create
    user = self.perform_create(serializer)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\dj_rest_auth\registration\views.py", line 92, in perform_create
    complete_signup(
    ^
  File "C:\dev\myProject\venv\Lib\site-packages\allauth\account\utils.py", line 103, in complete_signup
    return flows.signup.complete_signup(
           
  File "C:\dev\myProject\venv\Lib\site-packages\allauth\account\internal\flows\signup.py", line 114, in complete_signup
    return perform_login(request, login)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\allauth\account\internal\flows\login.py", line 93, in perform_login
    return resume_login(request, login)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\allauth\account\internal\flows\login.py", line 102, in resume_login
    response = ctrl.handle()
               ^^^^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\allauth\account\stages.py", line 119, in handle
    response, cont = stage.handle()
                     ^^^^^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\allauth\account\stages.py", line 157, in handle
    send_verification_email_at_login(self.request, login)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\allauth\account\internal\flows\email_verification.py", line 294, in send_verification_email_at_login
    sent = send_verification_email_at_real_login(request, login)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\allauth\account\internal\flows\email_verification.py", line 308, in send_verification_email_at_real_login
    return send_verification_email_to_address(request, address, signup=login.signup)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\allauth\account\internal\flows\email_verification.py", line 269, in send_verification_email_to_address
    confirmation = address.send_confirmation(request, signup=signup)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\allauth\account\models.py", line 104, in send_confirmation
    confirmation.send(request, signup=signup)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\allauth\account\models.py", line 133, in send
    get_adapter().send_confirmation_mail(request, self, signup)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\allauth\account\adapter.py", line 676, in send_confirmation_mail
    self.send_mail(email_template, emailconfirmation.email_address.email, ctx)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\allauth\account\adapter.py", line 211, in send_mail
    msg.send()
    ^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\django\core\mail\message.py", line 307, in send
    return self.get_connection(fail_silently).send_messages([self])
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\django\core\mail\backends\smtp.py", line 128, in send_messages
    new_conn_created = self.open()
                       ^^^^^^^^^^^
  File "C:\dev\myProject\venv\Lib\site-packages\django\core\mail\backends\smtp.py", line 93, in open
    self.connection.starttls(context=self.ssl_context)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python313\Lib\smtplib.py", line 779, in starttls
    self.sock = context.wrap_socket(self.sock,
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python313\Lib\ssl.py", line 455, in wrap_socket
    return self.sslsocket_class._create(
           
  File "C:\Python313\Lib\ssl.py", line 1076, in _create
    self.do_handshake()
    ^^^^^^^^^^^^^^^^^^^
  File "C:\Python313\Lib\ssl.py", line 1372, in do_handshake
    self._sslobj.do_handshake()
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^

Exception Type: SSLCertVerificationError at /auth/register/
Exception Value: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Basic Constraints of CA cert not marked critical (_ssl.c:1032)

Debug and Fix attempts: Trying to debug I wrote this in settings

import smtplib
import ssl
import certifi

print(certifi.where())
context = ssl.create_default_context(cafile=certifi.where())
print(context)

This prints:

C:\dev\myProject\venv\Lib\site-packages\certifi\cacert.pem
<ssl.SSLContext object at 0x0000024ACAE360D0>

And in line server.starttls(context=context) it raises ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:1032)

Also tried (but getting same error) changing email backend to a custom one as:

class EmailBackend(SMTPBackend):   
    @cached_property
    def ssl_context(self):
        if self.ssl_certfile or self.ssl_keyfile:
            ssl_context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_CLIENT)
            # set verify location:
            if hasattr(django_settings, 'CA_PATH') and django_settings.CA_PATH is not None:
                ssl_context.load_verify_locations(capath=django_settings.CA_PATH)
            ssl_context.load_cert_chain(self.ssl_certfile, self.ssl_keyfile)
            return ssl_context
        else:
            ssl_context = ssl.create_default_context()
            return ssl_context
Back to Top