Gmail displays text instead of HTML in JavaMail multipart messages

I’m working on a web app that sends email notifications using JavaMail. The emails are multipart with both text and HTML versions. When I test in Outlook, everything works perfectly - it shows the HTML version by default and switches to text when moved to spam folder.

But when I check the same emails in Gmail, it only shows the plain text version even though the HTML part is definitely there. Other HTML emails from different services display fine in Gmail.

What could be causing Gmail to ignore the HTML part? Am I missing some required headers or setting the content types wrong?

Here’s my code:

MimeMessage email = new MimeMessage(mailSession);
MimeMultipart content = new MimeMultipart("alternative");

try {
    MimeBodyPart plainText = new MimeBodyPart();
    plainText.setText(textContent, "utf-8");
    
    MimeBodyPart htmlContent = new MimeBodyPart();
    htmlContent.setContent(htmlBody, "text/html; charset=utf-8");
    
    content.addBodyPart(plainText);
    content.addBodyPart(htmlContent);
    email.setContent(content);
    
    email.setFrom(new InternetAddress(senderEmail));
    email.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipient));
    email.setSubject(emailSubject);
    email.setSentDate(new Date());
    
    Transport.send(email);
    
} catch (MessagingException ex) {
    ex.printStackTrace();
}

Had the same issue with Gmail about six months back. Turned out I was missing explicit charset declarations in my headers. Even if you’re setting charset in the HTML part, try adding plainText.setHeader("Content-Type", "text/plain; charset=utf-8") and htmlContent.setHeader("Content-Type", "text/html; charset=utf-8") right after setting the content. Gmail’s pickier about these headers than other clients. Also double-check your htmlBody for unclosed tags or broken HTML - Gmail just falls back to text if it can’t parse properly. Worth checking if you’ve got other headers like X-Mailer or Message-ID that might mess with Gmail’s rendering. Adding email.setHeader("MIME-Version", "1.0") before sending fixed the consistency issues I had across different providers.

Gmail’s super picky about multipart email structure compared to other clients. I hit this exact issue last year - turns out Gmail was rejecting the HTML part because of malformed content in the HTML itself. Your code structure looks fine, so the problem’s probably in your htmlBody variable content, not the JavaMail setup. Test with really simple HTML first - just basic tags, no CSS or complex markup. Also check if your HTML has anything suspicious that Gmail might flag as potentially harmful. In my case, certain CSS properties and embedded styles made Gmail fall back to text mode as a security measure. The order of parts matters too, but you’ve got that right with text first then HTML.

check ur HTML validation - Gmail’s way stricter than Outlook about broken markup. I’ve seen this when there’s a missing doctype or invalid nested tags. send a super basic HTML version first to test, then slowly add complexity until u find what breaks it. also, Gmail sometimes caches email rendering, so clear ur cache or test with a fresh account.