2026-07-15

Java Mail API - Encoding problems

Stefan Bogdanescu

Stefan Bogdanescu

Founder & Senior Architect

Java Mail API - Encoding problems

Mastering Character Encoding in Java Mail API: Solving the Tricky Mail Problem

As a developer dealing with cross-system communication, character encoding often becomes one of the most frustrating yet subtle bugs. When sending emails via protocols like SMTP, especially when dealing with international characters, the seemingly simple task of setting the text body can quickly devolve into a battle against corrupted symbols and bizarre character sequences.

I've encountered this exact scenario while working with the Java Mail API: successfully sending emails containing non-ASCII characters (like õäöü) to services like Gmail requires more than just setting the string; it demands a deep understanding of MIME encoding standards.

This post will dissect why you are seeing those weird symbols, analyze your failed attempts, and provide the definitive, robust solution for handling character encoding in Java email communications.

The Root of the Encoding Conflict

The core issue stems from the difference between how data is represented internally (in your IDE or standard String objects) and how it must be transmitted over the network using the MIME (Multipurpose Internet Mail Extensions) specification.

When you use methods like mailMessage.setText(yourString), the Mail API attempts to serialize this string into a format that the recipient's mail client can understand. If you simply pass raw characters, the system defaults to an assumption about the character set, which often leads to misinterpretation when dealing with complex scripts or extended Latin characters.

Your observation—that õäöü appears correctly in your IDE but gets corrupted (e.g., [ä„”?]) in Gmail—is classic evidence of a missing or incorrect Character Set declaration within the email headers. The goal is not just to store the text, but to explicitly tell the receiving server how that text is encoded so it can be decoded correctly by the client.

Analyzing Your Attempts and Best Practices

Let's look at the techniques you tried:

  1. Setting Headers:

    setHeader("Content-Type", "text/plain; charset=UTF-8");
    setHeader("Content-Encoding","ISO-8859-9"); // Attempting to specify encoding here
    setContent(message, "text/plain; charset=iso-8859-2");
    

    Attempting to manually set these headers is often insufficient or contradictory. The Mail API handles the complex MIME structure internally. Setting conflicting encodings (e.g., declaring UTF-8 but encoding using ISO-8859-9) causes the mismatch that results in garbled output.

  2. Using MimeUtility.encodeText():

    mailMessage.setText(MimeUtility.encodeText(mail.getMessage(), "UTF-8", "Q"));
    

    This method is designed to handle the necessary MIME encoding (often Quoted-Printable or Base64) for non-ASCII characters. The output you saw (=?UTF-8?Q?=C3=A4=E2=80=9E=E2=80=9D=EF=BF=BD;=0D=0A?=) is the standard way MIME encodes UTF-8 sequences, which is correct for transmission. The problem here wasn't the encoding itself, but how the resulting encoded string was finally presented to the recipient versus what the client expected.

  3. Manual String Concatenation:

    mailMessage.setText(strVar + "õäöü", "ISO-8859-1");
    

    This approach failed because you were trying to apply a character set hint after the text had already been potentially mangled or misinterpreted by the underlying framework, causing surrounding characters to be messed up.

The Correct Approach: Explicit UTF-8 Handling

The most reliable method is to ensure that your entire process—from input to transmission—is strictly UTF-8 compliant. You should let the Java Mail API handle the complex MIME encoding when you use modern character sets.

When sending emails, always prioritize setting the Content-Type header to explicitly state charset=UTF-8. The underlying library will correctly apply the necessary Base64 or Quoted-Printable encoding for transmission.

Here is a refined example demonstrating the correct flow:

import javax.mail.*;
import javax.mail.internet.*;
import java.util.Scanner;

public class MailSender {
    public static void main(String[] args) {
        try {
            // 1. Get user input (simulated for demonstration)
            Scanner scanner = new Scanner(System.in);
            String recipient = "recipient@example.com";
            String subject = "Test with special chars";
            String messageBody = "Hello world! This is a test with special characters: õäöü.";

            // 2. Setup Session and Message
            Session session = Session.getDefaultInstance(null, null);
            Message mailMessage = new MimeMessage(session);

            // 3. Set Sender and Recipients
            mailMessage.setFrom(new InternetAddress("sender@example.com"));
            mailMessage.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipient));

            // 4. Crucial Step: Explicitly set the encoding in the Content-Type header
            mailMessage.setContent(messageBody, "text/plain; charset=UTF-8");

            // 5. Set Subject
            mailMessage.setSubject(subject);

            // 6. Send the message
            Transport.send(mailMessage);

            System.out.println("Email sent successfully with UTF-8 encoding.");

        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }
}

Key Takeaway: By setting setContent(messageBody, "text/plain; charset=UTF-8");, you delegate the complex character transformation to the Mail API, ensuring that the resulting MIME message contains the necessary encoding instructions for the receiving server (like Gmail) to correctly decode the UTF-8 bytes before displaying the message. This robust handling is essential for building reliable systems, much like ensuring data integrity in application architecture, which is a principle we advocate at laravelcompany.com.

Conclusion

Encoding issues in email transmission are rarely about the characters themselves; they are almost always about the metadata—the headers and MIME structure—that describe those characters. Stop trying to manually force character set hints onto the text body. Instead, embrace modern standards: use UTF-8 exclusively for your message content, and let the established Mail API methods handle the intricate details of encoding and transmission. This ensures that your emails are readable, regardless of the complexity of the characters they contain.

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.