2026-07-15

How to send utf-8 e-mail?

Stefan Bogdanescu

Stefan Bogdanescu

Founder & Senior Architect

How to send utf-8 e-mail?

How to Send UTF-8 Emails: Mastering Character Encoding in Email Delivery

Sending emails containing complex characters, emojis, or non-Latin scripts—which is the essence of UTF-8—introduces a common hurdle for developers. While modern systems handle text internally using UTF-8, the underlying protocols used for email transmission (SMTP) often rely on older ASCII standards, leading to frustrating UnicodeEncodeError exceptions, as demonstrated by the script you provided.

As senior developers, we must understand that sending an email is not just about writing a string; it’s about correctly packaging that data according to established standards like MIME (Multipurpose Internet Mail Extensions). This guide will walk you through the technical challenges of UTF-8 email and provide robust solutions.

The Problem: ASCII vs. UTF-8 in SMTP

The traceback you encountered, UnicodeEncodeError: 'ascii' codec can't encode character '\u011b', clearly illustrates the issue. The smtplib library attempts to send the message over the SMTP connection, and because many legacy mail servers operate strictly on ASCII encoding, they cannot process multi-byte UTF-8 characters directly. The raw string data must be explicitly encoded into a byte sequence that the server understands, and this process requires careful handling of the entire message structure (headers and body).

The error occurs because you are attempting to encode a complex Unicode string into a simple ASCII encoding without properly formatting it as a proper MIME message first.

The Solution: Implementing Proper MIME Structure

To successfully send UTF-8 emails, you must adhere to the MIME standard. A MIME message wraps the content (HTML and plain text) in specific headers that tell the receiving mail client how to interpret the encoded data. This ensures that even if the transport layer is limited, the recipient can still correctly render the content.

The key steps are:

  1. Encode the Content: Ensure your source file is read and handled using UTF-8 encoding (encoding="utf-8").
  2. Construct MIME Parts: Create separate parts for the HTML body and the plain text body, each with appropriate Content-Type headers.
  3. Set Charset: Explicitly set the character set of the entire message to UTF-8 using msg.set_charset('utf-8').

Your original approach was close, but it missed the critical step of properly structuring the multi-part message before transmission.

Refactoring for Robust UTF-8 Email Sending

Instead of attempting to inject dynamic content via simple string substitutions into a raw template, we should build the email using structured objects. While Python's standard library can handle this, in large-scale application development, leveraging robust frameworks—like those found within the Laravel ecosystem—helps manage complex data flows and external services efficiently, ensuring that foundational tasks like communication are handled securely and reliably.

Here is a conceptual refactoring of the process, focusing on correct MIME construction:

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

def send_utf8_email(from_addr, to_addr, subject, body_html, body_text):
    # 1. Create the main container for the message
    msg = MIMEMultipart('alternative')
    msg['From'] = from_addr
    msg['To'] = to_addr
    msg['Subject'] = subject

    # 2. Attach parts with explicit UTF-8 encoding (MIME handles the complexity)
    part1 = MIMEText(body_html, 'html', 'utf-8')
    part2 = MIMEText(body_text, 'plain', 'utf-8')
    
    msg.attach(part1)
    msg.attach(part2)

    try:
        # 3. Send the fully constructed message string
        server = smtplib.SMTP('smtp.example.com', 587) # Use a real SMTP server here
        server.starttls()
        server.login("user", "password")
        
        # The .as_string() method now handles the proper Base64 encoding necessary for transport
        server.sendmail(from_addr, to_addr, msg.as_string())
        print("Email sent successfully!")
        return True
    except Exception as ex:
        print(f"Error sending email: {ex}")
        return False
    finally:
        server.quit()

# Example usage (assuming body_html and body_text are already UTF-8 strings)
# send_utf8_email("sender@example.com", "receiver@example.com", "Test", html_content, text_content)

Conclusion

Sending UTF-8 emails successfully requires moving beyond simple string manipulation and embracing the standards of MIME. By structuring your email as a multi-part message with explicit character set declarations, you ensure that the data is correctly encoded and packaged for reliable transmission across different mail infrastructure. Always prioritize robust encoding practices when dealing with international text to avoid runtime errors and deliver professional communication consistently.

Note: Blog content is currently available in English.

Tags:

Enhance your marketing setup with your own email marketing platform.

Join the growing number of SaaS platforms using Laravel Mail to offer email marketing solutions to their customers.