Python mail sending error: "CERTIFICATE VERIFY FAILED" & "WRONG VERSION NUMBER"

777 Views Asked by At

Through the smtp email server, I'm attempting to send an email. I tried using the SMTP SSL() and starttls() methods to send emails, but both returned errors: WRONG VERSION NUMBER for SMTP SSL() and CERTIFICATE VERIFY FAILED for starttls(). Below are the given tracebacks.

Traceback of SMTP_SSL():

  File "mail_sender_test.py", line 15, in <module>
    with smtplib.SMTP_SSL(smtp_server, smtp_port, context=context) as server:
  File "/usr/lib64/python3.6/smtplib.py", line 1031, in __init__
    source_address)
  File "/usr/lib64/python3.6/smtplib.py", line 251, in __init__
    (code, msg) = self.connect(host, port)
  File "/usr/lib64/python3.6/smtplib.py", line 336, in connect
    self.sock = self._get_socket(host, port, self.timeout)
  File "/usr/lib64/python3.6/smtplib.py", line 1039, in _get_socket
    server_hostname=self._host)
  File "/usr/lib64/python3.6/ssl.py", line 365, in wrap_socket
    _context=self, _session=session)
  File "/usr/lib64/python3.6/ssl.py", line 776, in __init__
    self.do_handshake()
  File "/usr/lib64/python3.6/ssl.py", line 1036, in do_handshake
    self._sslobj.do_handshake()
  File "/usr/lib64/python3.6/ssl.py", line 648, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:897)

Traceback of starttls():

  File "mail_sender_test.py", line 21, in <module>
    server.starttls(context=context)
  File "/usr/lib64/python3.6/smtplib.py", line 771, in starttls
    server_hostname=self._host)
  File "/usr/lib64/python3.6/ssl.py", line 365, in wrap_socket
    _context=self, _session=session)
  File "/usr/lib64/python3.6/ssl.py", line 776, in __init__
    self.do_handshake()
  File "/usr/lib64/python3.6/ssl.py", line 1036, in do_handshake
    self._sslobj.do_handshake()
  File "/usr/lib64/python3.6/ssl.py", line 648, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:897)

Here is the sample code.

import smtplib, ssl

smtp_server = "1.2.3.4"
smtp_port = 25
smtp_password = "1234"
sender_address = "[email protected]"
receiver_address = "[email protected]"

message = """\
Subject: Hi there

This message is sent from Python."""

context = ssl.create_default_context()
with smtplib.SMTP_SSL(smtp_server, smtp_port, context=context) as server:
    server.login(sender_address, smtp_password)
    server.sendmail(sender_address, receiver_address, message)

# with smtplib.SMTP(smtp_server, smtp_port) as server:
#     server.ehlo()  # Can be omitted
#     server.starttls(context=context)
#     server.ehlo()  # Can be omitted
#     server.login(sender_address, smtp_password)
#     server.sendmail(sender_address, receiver_address, message)

If anyone could assist in solving the problem, that would be wonderful.

Thanks

1

There are 1 best solutions below

1
Steffen Ullrich On
smtp_port = 25
...
with smtplib.SMTP_SSL(smtp_server, smtp_port, context=context) as server:

Port 25 is for plain SMTP with a possible upgrade to TLS with starttls. SMTP_SSL instead is for SMTP directly over TLS. Thus your code tries to speak TLS with a non-TLS peer. The peer sends something npn-TLS (likely something like 220 ...) which gets wrongly interpreted as TLS though, leading to WRONG_VERSION_NUMBER.

... CERTIFICATE VERIFY FAILED for starttls()

That's the case if the servers certificate cannot be verified. Reasons are unknown since nothing is known about your server, its certificate and your trust store. Note that if you have a self-signed certificate you need to explicitly trust it by setting the SSL context appropriately.