When using QQ Mail's SMTP server to send emails via Python's smtplib, you may encounter the error:
(550, b'The "From" header is missing or invalid. Please follow RFC5322, RFC2047, RFC822 standard protocol. https://service.mail.qq.com/detail/124/995.')
This typically happens when the From header in the email is incorrectly encoded.
Problematic Code
Consider the following Python 3.12 code that attempts to send a plain-text email:
import smtplib
from email.header import Header
from email.mime.text import MIMEText
class Mail:
def __init__(self, mail_pass, sender, receivers):
self.mail_host = "smtp.qq.com"
self.mail_pass = mail_pass
self.sender = sender
self.receivers = receivers
def send(self, subject, content):
message = MIMEText(content, 'plain', 'utf-8')
message['From'] = Header(self.sender)
message['Subject'] = Header(subject, 'utf-8')
try:
smtpObj = smtplib.SMTP_SSL(self.mail_host, 465)
smtpObj.login(self.sender, self.mail_pass)
smtpObj.sendmail(self.sender, self.receivers, message.as_string())
smtpObj.quit()
print("Sent successfully")
except smtplib.SMTPException as e:
print(f"Failed to send: {e}")
if __name__ == '__main__':
mail = Mail("your_auth_code", "you@qq.com", ["recipient@gmail.com"])
mail.send("Test Subject", "Hello, this is a test message.")
Root Cause
QQ Mail enforces strict validation of the From header according to RFC standards. The problem arises because Header(self.sender) applies UTF-8 encoding to the email address, turning you@qq.com into =?utf-8?q?you=40qq=2Ecom?=. This encoded representation is not a valid RFC5322 address, so the QQ server rejects it with error 550.
Solution
Do not use Header() for the From field. The From header should contain the bare email address (or a plain ASCII display name + email in brackets). Modify the assignmant as follows:
message['From'] = self.sender
This sets the From header directly to the string you@qq.com with out any encoding. The Subject header remains fine with Header(subject, 'utf-8') because subjects often contain non-ASCII characters.
Corrected Code
import smtplib
from email.header import Header
from email.mime.text import MIMEText
class Mail:
def __init__(self, mail_pass, sender, receivers):
self.mail_host = "smtp.qq.com"
self.mail_pass = mail_pass
self.sender = sender
self.receivers = receivers
def send(self, subject, content):
message = MIMEText(content, 'plain', 'utf-8')
message['From'] = self.sender # <-- fixed: no Header()
message['Subject'] = Header(subject, 'utf-8')
try:
smtpObj = smtplib.SMTP_SSL(self.mail_host, 465)
smtpObj.login(self.sender, self.mail_pass)
smtpObj.sendmail(self.sender, self.receivers, message.as_string())
smtpObj.quit()
print("Sent successfully")
except smtplib.SMTPException as e:
print(f"Failed to send: {e}")
if __name__ == '__main__':
mail = Mail("your_auth_code", "you@qq.com", ["recipient@gmail.com"])
mail.send("Test Subject", "Hello, this is a test message.")
Verification
After the fix, inspect the generated MIME message (for example, by printing message). The From header should appear as a plain email address without RFC2047 encoding:
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
From: you@qq.com
Subject: =?utf-8?q?Test_Subject?=
<base64-encoded body>
When you run the corrected script, the email will be sent successfully through QQ Mail's SMTP server.