1

I'm trying to send a basic email with an attached document. The example I have works fine with a google address smtp.google.com, but when I try changing it over to smtp.office365.com, I get this error: [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:852).

This is a domain email that runs through the office365 SMTP server as a host for the email service. I've checked with the IT team, and they have turned on SMTP authentication on the account.

Obviously, this has been done before, so I have checked my code against this example, but don't see any obvious differences that could be causing it. I've also doubled checked the smtplib documentation, and smtp.office365.com is a valid, recognized SMTP address.

I've written this out as follows (note the confidential credentials which prevent a minimal reproducible example). I've noted where the error occurs, it's almost like smtplib is not recognizing the office365 SMTP address.

 def send_email(self, html_message): # Create a text/plain message formatted_date = datetime.datetime.now().strftime('%Y%m%d') msg_root = MIMEMultipart('related') msg_root['Subject'] = self.client.client_name + 'Test Forecast' msg_root['From'] = self.config.get_email_from recipients = self.client.recipient_email recipients = recipients.split(', ') body = MIMEText(html_message, 'html') msg_root.attach(body) filename = self.client.city + ', ' + self.client.state # PDF attachment if self.client.use_pdf: filepath = self.config.get_email_pdf_file_path fp = open(filepath, 'rb') att = email.mime.application.MIMEApplication(fp.read(), _subtype="pdf") fp.close() att.add_header('Content-Disposition', 'attachment', filename=filename + '.pdf') msg_root.attach(att) # SSL port config port = 587 # Create a secure SSL context context = ssl.create_default_context() # Connect with smtplib.SMTP_SSL("smtp.office365.com", port, context=context) as server: # Error on this line server.ehlo() server.starttls() server.login(self.config.get_email_from, self.config.get_email_password) print("Sending email report...") # Send email server.sendmail(self.config.get_email_from, recipients, msg_root.as_string()) print("Your email was sent!") 

2 Answers 2

2
+25

According to error: [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:852) You should use 465 port because you are using SSL protocol and 587 port is for TLS protocol.

Sign up to request clarification or add additional context in comments.

3 Comments

To be more precise, port 465 is SMTP over SSL/TLS, in that it's encrypted from connection. Port 587 is SMTP submission, and answers non-encrypted, but is generally upgraded with the StartTLS command.
And starttls should not be issued on a port that was started with SSL/TLS. Eg, if you use SMTP_SSL(), don't use starttls. If you use SMTP(), you should use starttls.
Well, this is very close and definitely part of the problem, but not the full solution. Going to post the full one. Though, this was extremely helpful in getting there, so have an upvote :)
0

It appears that because Microsoft uses port 587 for SMTP and the external domain we're using doesn't communicate via SSL, I had to change the port over to 587, remove the SSL argument from the method, and remove the context. With it now using SMTP rather than SSL, starttls was also necessary.

The working version looks like this:

 port = 587 # Connect with smtplib.SMTP("smtp.office365.com", port) as server: server.ehlo() server.starttls() server.ehlo() server.login(self.config.get_email_from, self.config.get_email_password) print("Sending email report...") # Send email server.sendmail(self.config.get_email_from, recipients, msg_root.as_string()) print("Your email was sent!") 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.